d3d9/tests: Add a couple of fog tests.
[wine.git] / dlls / d3d9 / tests / visual.c
blob499ea5f77edad4193424572f158e7fbda6ff8e1e
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 const float ident_mat[16] =
933 1.0f, 0.0f, 0.0f, 0.0f,
934 0.0f, 1.0f, 0.0f, 0.0f,
935 0.0f, 0.0f, 1.0f, 0.0f,
936 0.0f, 0.0f, 0.0f, 1.0f
938 const float world_mat1[16] =
940 1.0f, 0.0f, 0.0f, 0.0f,
941 0.0f, 1.0f, 0.0f, 0.0f,
942 0.0f, 0.0f, 1.0f, 0.0f,
943 0.0f, 0.0f, -0.5f, 1.0f
945 const float world_mat2[16] =
947 1.0f, 0.0f, 0.0f, 0.0f,
948 0.0f, 1.0f, 0.0f, 0.0f,
949 0.0f, 0.0f, 1.0f, 0.0f,
950 0.0f, 0.0f, 1.0f, 1.0f
952 const float proj_mat[16] =
954 1.0f, 0.0f, 0.0f, 0.0f,
955 0.0f, 1.0f, 0.0f, 0.0f,
956 0.0f, 0.0f, 1.0f, 0.0f,
957 0.0f, 0.0f, -1.0f, 1.0f
960 const struct sVertex far_quad1[] =
962 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
963 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
964 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
965 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
967 const struct sVertex far_quad2[] =
969 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
970 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
971 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
972 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
975 memset(&caps, 0, sizeof(caps));
976 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
977 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
979 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
981 /* Setup initial states: No lighting, fog on, fog color */
982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
983 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
985 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
987 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
989 /* First test: Both table fog and vertex fog off */
990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
991 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
993 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
995 /* Start = 0, end = 1. Should be default, but set them */
996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
997 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
999 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1001 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1004 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1005 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1006 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1007 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1008 sizeof(untransformed_1[0]));
1009 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1011 /* That makes it use the Z value */
1012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1013 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1014 /* Untransformed, vertex fog != none (or table fog != none):
1015 * Use the Z value as input into the equation
1017 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1018 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1019 sizeof(untransformed_2[0]));
1020 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1022 /* transformed verts */
1023 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1024 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1025 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1026 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1027 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1028 sizeof(transformed_1[0]));
1029 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1032 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1033 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1034 * equation
1036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1037 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1038 sizeof(transformed_2[0]));
1039 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1041 hr = IDirect3DDevice9_EndScene(device);
1042 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1044 else
1046 ok(FALSE, "BeginScene failed\n");
1049 color = getPixelColor(device, 160, 360);
1050 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1051 color = getPixelColor(device, 160, 120);
1052 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1053 color = getPixelColor(device, 480, 120);
1054 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1055 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1057 color = getPixelColor(device, 480, 360);
1058 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1060 else
1062 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1063 * The settings above result in no fogging with vertex fog
1065 color = getPixelColor(device, 480, 120);
1066 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1067 trace("Info: Table fog not supported by this device\n");
1069 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1071 /* Now test the special case fogstart == fogend */
1072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1073 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1075 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1077 start = 512;
1078 end = 512;
1079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1080 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1082 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1084 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1085 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1087 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1089 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1091 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1092 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1093 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1094 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1095 * color and has fixed fogstart and fogend.
1097 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1098 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1099 sizeof(untransformed_1[0]));
1100 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1101 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1102 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1103 sizeof(untransformed_2[0]));
1104 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1106 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1107 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1108 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1109 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1110 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1111 sizeof(transformed_1[0]));
1112 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1114 hr = IDirect3DDevice9_EndScene(device);
1115 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1117 else
1119 ok(FALSE, "BeginScene failed\n");
1121 color = getPixelColor(device, 160, 360);
1122 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1123 color = getPixelColor(device, 160, 120);
1124 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1125 color = getPixelColor(device, 480, 120);
1126 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1127 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1129 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1130 * but without shaders it seems to work everywhere
1132 end = 0.2;
1133 start = 0.8;
1134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1139 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1141 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1142 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1143 * so skip this for now
1145 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1146 const char *mode = (i ? "table" : "vertex");
1147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1148 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1150 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1152 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1153 hr = IDirect3DDevice9_BeginScene(device);
1154 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1155 if(SUCCEEDED(hr)) {
1156 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1157 4, 5, 6, 6, 7, 4,
1158 8, 9, 10, 10, 11, 8,
1159 12, 13, 14, 14, 15, 12};
1161 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1162 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1163 sizeof(rev_fog_quads[0]));
1164 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1166 hr = IDirect3DDevice9_EndScene(device);
1167 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1169 color = getPixelColor(device, 160, 360);
1170 ok(color_match(color, 0x0000ff00, 1),
1171 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1173 color = getPixelColor(device, 160, 120);
1174 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1175 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1177 color = getPixelColor(device, 480, 120);
1178 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1179 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1181 color = getPixelColor(device, 480, 360);
1182 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1184 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1186 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1187 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1188 break;
1192 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1194 /* A simple fog + non-identity world matrix test */
1195 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1196 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1198 start = 0.0;
1199 end = 1.0;
1200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1201 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1203 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1205 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1207 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1210 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1212 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1214 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1215 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1217 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1218 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1219 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1221 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1222 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1223 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1225 hr = IDirect3DDevice9_EndScene(device);
1226 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1228 else
1230 ok(FALSE, "BeginScene failed\n");
1233 color = getPixelColor(device, 160, 360);
1234 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1235 color = getPixelColor(device, 160, 120);
1236 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
1238 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1240 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1241 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1242 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1243 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1244 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1246 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1247 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1249 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1251 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1252 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1254 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1255 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1256 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1258 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1259 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1260 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1262 hr = IDirect3DDevice9_EndScene(device);
1263 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1265 else
1267 ok(FALSE, "BeginScene failed\n");
1270 color = getPixelColor(device, 160, 360);
1271 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1272 color = getPixelColor(device, 160, 120);
1273 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
1275 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1277 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1278 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1279 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1280 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1282 else
1284 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1287 /* Turn off the fog master switch to avoid confusing other tests */
1288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1289 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1291 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1293 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1296 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1297 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1298 * regardless of the actual addressing mode set. The way this test works is
1299 * that we sample in one of the corners of the cubemap with filtering enabled,
1300 * and check the interpolated color. There are essentially two reasonable
1301 * things an implementation can do: Either pick one of the faces and
1302 * interpolate the edge texel with itself (i.e., clamp within the face), or
1303 * interpolate between the edge texels of the three involved faces. It should
1304 * never involve the border color or the other side (texcoord wrapping) of a
1305 * face in the interpolation. */
1306 static void test_cube_wrap(IDirect3DDevice9 *device)
1308 static const float quad[][6] = {
1309 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1310 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1311 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1312 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1315 static const D3DVERTEXELEMENT9 decl_elements[] = {
1316 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1317 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1318 D3DDECL_END()
1321 static const struct {
1322 D3DTEXTUREADDRESS mode;
1323 const char *name;
1324 } address_modes[] = {
1325 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1326 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1327 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1328 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1329 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1332 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1333 IDirect3DCubeTexture9 *texture = NULL;
1334 IDirect3DSurface9 *surface = NULL;
1335 IDirect3DSurface9 *face_surface;
1336 D3DLOCKED_RECT locked_rect;
1337 HRESULT hr;
1338 UINT x;
1339 INT y, face;
1341 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1342 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1343 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1344 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1346 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1347 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1348 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1350 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1351 D3DPOOL_DEFAULT, &texture, NULL);
1352 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1354 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1355 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1357 for (y = 0; y < 128; ++y)
1359 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1360 for (x = 0; x < 64; ++x)
1362 *ptr++ = 0xff0000ff;
1364 for (x = 64; x < 128; ++x)
1366 *ptr++ = 0xffff0000;
1370 hr = IDirect3DSurface9_UnlockRect(surface);
1371 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1373 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1374 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1376 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1377 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1379 IDirect3DSurface9_Release(face_surface);
1381 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1382 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1384 for (y = 0; y < 128; ++y)
1386 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1387 for (x = 0; x < 64; ++x)
1389 *ptr++ = 0xffff0000;
1391 for (x = 64; x < 128; ++x)
1393 *ptr++ = 0xff0000ff;
1397 hr = IDirect3DSurface9_UnlockRect(surface);
1398 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1400 /* Create cube faces */
1401 for (face = 1; face < 6; ++face)
1403 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1404 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1406 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1407 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1409 IDirect3DSurface9_Release(face_surface);
1412 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1413 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1415 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1416 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1417 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1418 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1419 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1420 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1423 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1425 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1427 DWORD color;
1429 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1430 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1431 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1432 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1434 hr = IDirect3DDevice9_BeginScene(device);
1435 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1438 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1440 hr = IDirect3DDevice9_EndScene(device);
1441 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1443 color = getPixelColor(device, 320, 240);
1444 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1445 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1446 color, address_modes[x].name);
1448 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1449 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1451 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1452 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1455 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1456 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1458 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1459 IDirect3DCubeTexture9_Release(texture);
1460 IDirect3DSurface9_Release(surface);
1463 static void offscreen_test(IDirect3DDevice9 *device)
1465 HRESULT hr;
1466 IDirect3DTexture9 *offscreenTexture = NULL;
1467 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1468 DWORD color;
1470 static const float quad[][5] = {
1471 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1472 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1473 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1474 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1477 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1478 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1480 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1481 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1482 if(!offscreenTexture) {
1483 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1484 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1485 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1486 if(!offscreenTexture) {
1487 skip("Cannot create an offscreen render target\n");
1488 goto out;
1492 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1493 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1494 if(!backbuffer) {
1495 goto out;
1498 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1499 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1500 if(!offscreen) {
1501 goto out;
1504 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1505 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1507 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1508 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1509 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1510 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1511 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1512 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1513 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1514 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1516 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1518 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1519 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1520 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1521 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1522 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1524 /* Draw without textures - Should result in a white quad */
1525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1526 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1528 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1529 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1530 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1531 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1533 /* This time with the texture */
1534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1535 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1537 IDirect3DDevice9_EndScene(device);
1540 /* Center quad - should be white */
1541 color = getPixelColor(device, 320, 240);
1542 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1543 /* Some quad in the cleared part of the texture */
1544 color = getPixelColor(device, 170, 240);
1545 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1546 /* Part of the originally cleared back buffer */
1547 color = getPixelColor(device, 10, 10);
1548 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1549 if(0) {
1550 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1551 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1552 * the offscreen rendering mode this test would succeed or fail
1554 color = getPixelColor(device, 10, 470);
1555 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1558 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1560 out:
1561 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1562 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1564 /* restore things */
1565 if(backbuffer) {
1566 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1567 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1568 IDirect3DSurface9_Release(backbuffer);
1570 if(offscreenTexture) {
1571 IDirect3DTexture9_Release(offscreenTexture);
1573 if(offscreen) {
1574 IDirect3DSurface9_Release(offscreen);
1578 /* This test tests fog in combination with shaders.
1579 * What's tested: linear fog (vertex and table) with pixel shader
1580 * linear table fog with non foggy vertex shader
1581 * vertex fog with foggy vertex shader, non-linear
1582 * fog with shader, non-linear fog with foggy shader,
1583 * linear table fog with foggy shader
1585 static void fog_with_shader_test(IDirect3DDevice9 *device)
1587 HRESULT hr;
1588 DWORD color;
1589 union {
1590 float f;
1591 DWORD i;
1592 } start, end;
1593 unsigned int i, j;
1595 /* basic vertex shader without fog computation ("non foggy") */
1596 static const DWORD vertex_shader_code1[] = {
1597 0xfffe0101, /* vs_1_1 */
1598 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1599 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1600 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1601 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1602 0x0000ffff
1604 /* basic vertex shader with reversed fog computation ("foggy") */
1605 static const DWORD vertex_shader_code2[] = {
1606 0xfffe0101, /* vs_1_1 */
1607 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1608 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1609 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1610 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1611 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1612 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1613 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1614 0x0000ffff
1616 /* basic pixel shader */
1617 static const DWORD pixel_shader_code[] = {
1618 0xffff0101, /* ps_1_1 */
1619 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1620 0x0000ffff
1623 static struct vertex quad[] = {
1624 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1625 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1626 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1627 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1630 static const D3DVERTEXELEMENT9 decl_elements[] = {
1631 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1632 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1633 D3DDECL_END()
1636 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1637 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1638 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1640 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1641 static const struct test_data_t {
1642 int vshader;
1643 int pshader;
1644 D3DFOGMODE vfog;
1645 D3DFOGMODE tfog;
1646 unsigned int color[11];
1647 } test_data[] = {
1648 /* only pixel shader: */
1649 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1650 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1651 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1652 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1653 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1654 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1655 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1656 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1657 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1658 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1659 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1660 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1661 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1665 /* vertex shader */
1666 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1667 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1668 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1669 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1670 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1671 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1672 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1673 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1674 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1676 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1677 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1678 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1679 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1680 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1681 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1683 /* vertex shader and pixel shader */
1684 /* The next 4 tests would read the fog coord output, but it isn't available.
1685 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1686 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1687 * These tests should be disabled if some other hardware behaves differently
1689 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1690 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1691 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1692 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1693 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1694 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1695 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1696 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1697 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1698 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1699 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1700 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1702 /* These use the Z coordinate with linear table fog */
1703 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1704 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1705 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1706 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1707 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1708 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1709 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1710 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1711 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1712 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1713 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1714 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1716 /* Non-linear table fog without fog coord */
1717 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1718 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1719 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1720 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1721 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1722 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1724 #if 0 /* FIXME: these fail on GeForce 8500 */
1725 /* foggy vertex shader */
1726 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1727 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1728 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1729 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1730 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1731 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1732 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1733 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1734 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1735 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1736 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1737 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1738 #endif
1740 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1741 * all using the fixed fog-coord linear fog
1743 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1744 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1745 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1746 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1747 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1748 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1749 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1750 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1751 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1752 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1753 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1754 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1756 /* These use table fog. Here the shader-provided fog coordinate is
1757 * ignored and the z coordinate used instead
1759 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1760 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1761 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1762 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1763 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1764 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1765 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1766 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1767 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1770 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1771 start.f=0.1f;
1772 end.f=0.9f;
1774 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1775 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1776 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1777 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1778 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1779 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1780 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1781 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1783 /* Setup initial states: No lighting, fog on, fog color */
1784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1785 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1787 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1789 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1790 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1791 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1793 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1794 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1796 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1798 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1800 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1802 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1804 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1806 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1807 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1808 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1809 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1811 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1813 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1815 for(j=0; j < 11; j++)
1817 /* Don't use the whole zrange to prevent rounding errors */
1818 quad[0].z = 0.001f + (float)j / 10.02f;
1819 quad[1].z = 0.001f + (float)j / 10.02f;
1820 quad[2].z = 0.001f + (float)j / 10.02f;
1821 quad[3].z = 0.001f + (float)j / 10.02f;
1823 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1824 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1826 hr = IDirect3DDevice9_BeginScene(device);
1827 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1832 hr = IDirect3DDevice9_EndScene(device);
1833 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1835 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1836 color = getPixelColor(device, 128, 240);
1837 ok(color_match(color, test_data[i].color[j], 13),
1838 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1839 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1841 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1845 /* reset states */
1846 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1847 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1848 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1849 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1850 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1851 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1853 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1855 IDirect3DVertexShader9_Release(vertex_shader[1]);
1856 IDirect3DVertexShader9_Release(vertex_shader[2]);
1857 IDirect3DPixelShader9_Release(pixel_shader[1]);
1858 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1861 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1862 unsigned int i, x, y;
1863 HRESULT hr;
1864 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1865 D3DLOCKED_RECT locked_rect;
1867 /* Generate the textures */
1868 for(i=0; i<2; i++)
1870 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1871 D3DPOOL_MANAGED, &texture[i], NULL);
1872 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1874 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1875 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1876 for (y = 0; y < 128; ++y)
1878 if(i)
1879 { /* Set up black texture with 2x2 texel white spot in the middle */
1880 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1881 for (x = 0; x < 128; ++x)
1883 if(y>62 && y<66 && x>62 && x<66)
1884 *ptr++ = 0xffffffff;
1885 else
1886 *ptr++ = 0xff000000;
1889 else
1890 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1891 * (if multiplied with bumpenvmat)
1893 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1894 for (x = 0; x < 128; ++x)
1896 if(abs(x-64)>abs(y-64))
1898 if(x < 64)
1899 *ptr++ = 0xc000;
1900 else
1901 *ptr++ = 0x4000;
1903 else
1905 if(y < 64)
1906 *ptr++ = 0x0040;
1907 else
1908 *ptr++ = 0x00c0;
1913 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1914 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1916 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1917 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919 /* Disable texture filtering */
1920 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1921 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1922 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1923 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1925 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1926 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1928 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1932 /* test the behavior of the texbem instruction
1933 * with normal 2D and projective 2D textures
1935 static void texbem_test(IDirect3DDevice9 *device)
1937 HRESULT hr;
1938 DWORD color;
1939 int i;
1941 static const DWORD pixel_shader_code[] = {
1942 0xffff0101, /* ps_1_1*/
1943 0x00000042, 0xb00f0000, /* tex t0*/
1944 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1945 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1946 0x0000ffff
1948 static const DWORD double_texbem_code[] = {
1949 0xffff0103, /* ps_1_3 */
1950 0x00000042, 0xb00f0000, /* tex t0 */
1951 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1952 0x00000042, 0xb00f0002, /* tex t2 */
1953 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1954 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1955 0x0000ffff /* end */
1959 static const float quad[][7] = {
1960 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1961 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1962 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1963 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1965 static const float quad_proj[][9] = {
1966 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1967 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1968 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1969 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1972 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1973 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1974 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1975 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1976 D3DDECL_END()
1978 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1979 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1980 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1981 D3DDECL_END()
1982 } };
1984 /* use asymmetric matrix to test loading */
1985 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1987 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1988 IDirect3DPixelShader9 *pixel_shader = NULL;
1989 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1990 D3DLOCKED_RECT locked_rect;
1992 generate_bumpmap_textures(device);
1994 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1995 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1996 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1997 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1998 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2000 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2001 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2006 for(i=0; i<2; i++)
2008 if(i)
2010 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2011 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2014 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2015 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2016 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2017 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2019 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2020 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2021 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2022 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2024 hr = IDirect3DDevice9_BeginScene(device);
2025 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2027 if(!i)
2028 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2029 else
2030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2033 hr = IDirect3DDevice9_EndScene(device);
2034 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2036 color = getPixelColor(device, 320-32, 240);
2037 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2038 color = getPixelColor(device, 320+32, 240);
2039 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2040 color = getPixelColor(device, 320, 240-32);
2041 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2042 color = getPixelColor(device, 320, 240+32);
2043 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2045 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2046 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2048 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2049 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2050 IDirect3DPixelShader9_Release(pixel_shader);
2052 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2053 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2054 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2057 /* clean up */
2058 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2059 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2061 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2062 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2064 for(i=0; i<2; i++)
2066 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2067 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2068 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2069 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2070 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2071 IDirect3DTexture9_Release(texture);
2074 /* Test double texbem */
2075 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2076 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2077 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2078 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2079 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2080 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2081 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2082 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2084 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2085 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2086 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2087 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2089 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2090 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2092 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2093 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2094 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2095 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2096 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2097 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2100 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2101 #define tex 0x00ff0000
2102 #define tex1 0x0000ff00
2103 #define origin 0x000000ff
2104 static const DWORD pixel_data[] = {
2105 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2106 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2107 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2108 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2109 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2110 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2111 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2112 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2114 #undef tex1
2115 #undef tex2
2116 #undef origin
2118 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2119 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2120 for(i = 0; i < 8; i++) {
2121 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2123 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2124 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2127 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2128 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2129 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2130 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2131 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2133 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2134 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2135 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2136 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2137 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2138 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2140 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2141 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2142 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2143 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2144 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2145 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2146 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2148 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2149 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2151 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2152 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2153 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2154 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2155 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2156 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2157 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2158 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2159 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2160 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2162 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2163 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2164 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2165 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2166 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2167 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2168 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2169 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2170 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2171 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2172 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2173 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2174 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2175 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2176 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2177 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2179 hr = IDirect3DDevice9_BeginScene(device);
2180 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2181 if(SUCCEEDED(hr)) {
2182 static const float double_quad[] = {
2183 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2184 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2185 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2186 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2190 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2191 hr = IDirect3DDevice9_EndScene(device);
2192 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2194 color = getPixelColor(device, 320, 240);
2195 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2197 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2198 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2199 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2200 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2201 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2202 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2203 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2204 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2205 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2206 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2208 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2209 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2211 IDirect3DPixelShader9_Release(pixel_shader);
2212 IDirect3DTexture9_Release(texture);
2213 IDirect3DTexture9_Release(texture1);
2214 IDirect3DTexture9_Release(texture2);
2217 static void z_range_test(IDirect3DDevice9 *device)
2219 const struct vertex quad[] =
2221 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2222 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2223 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2224 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2226 const struct vertex quad2[] =
2228 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2229 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2230 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2231 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2234 const struct tvertex quad3[] =
2236 { 0, 240, 1.1f, 1.0, 0xffffff00},
2237 { 0, 480, 1.1f, 1.0, 0xffffff00},
2238 { 640, 240, -1.1f, 1.0, 0xffffff00},
2239 { 640, 480, -1.1f, 1.0, 0xffffff00},
2241 const struct tvertex quad4[] =
2243 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2244 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2245 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2246 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2248 HRESULT hr;
2249 DWORD color;
2250 IDirect3DVertexShader9 *shader;
2251 IDirect3DVertexDeclaration9 *decl;
2252 D3DCAPS9 caps;
2253 const DWORD shader_code[] = {
2254 0xfffe0101, /* vs_1_1 */
2255 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2256 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2257 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2258 0x0000ffff /* end */
2260 static const D3DVERTEXELEMENT9 decl_elements[] = {
2261 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2262 D3DDECL_END()
2265 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2267 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2268 * then call Present. Then clear the color buffer to make sure it has some defined content
2269 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2270 * by the depth value.
2272 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2273 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2274 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2275 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2277 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2280 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2282 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2286 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2287 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2288 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2290 hr = IDirect3DDevice9_BeginScene(device);
2291 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2292 if(hr == D3D_OK)
2294 /* Test the untransformed vertex path */
2295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2296 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2300 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2302 /* Test the transformed vertex path */
2303 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2304 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2307 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2311 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2313 hr = IDirect3DDevice9_EndScene(device);
2314 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2317 /* Do not test the exact corner pixels, but go pretty close to them */
2319 /* Clipped because z > 1.0 */
2320 color = getPixelColor(device, 28, 238);
2321 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2322 color = getPixelColor(device, 28, 241);
2323 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2325 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2327 else
2329 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2332 /* Not clipped, > z buffer clear value(0.75) */
2333 color = getPixelColor(device, 31, 238);
2334 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2335 color = getPixelColor(device, 31, 241);
2336 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2337 color = getPixelColor(device, 100, 238);
2338 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2339 color = getPixelColor(device, 100, 241);
2340 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2342 /* Not clipped, < z buffer clear value */
2343 color = getPixelColor(device, 104, 238);
2344 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2345 color = getPixelColor(device, 104, 241);
2346 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2347 color = getPixelColor(device, 318, 238);
2348 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2349 color = getPixelColor(device, 318, 241);
2350 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2352 /* Clipped because z < 0.0 */
2353 color = getPixelColor(device, 321, 238);
2354 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2355 color = getPixelColor(device, 321, 241);
2356 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2358 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2360 else
2362 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2366 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2368 /* Test the shader path */
2369 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2370 skip("Vertex shaders not supported\n");
2371 goto out;
2373 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2374 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2375 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2376 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2378 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2380 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2381 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2382 IDirect3DDevice9_SetVertexShader(device, shader);
2383 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2385 hr = IDirect3DDevice9_BeginScene(device);
2386 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2387 if(hr == D3D_OK)
2389 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2390 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2391 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2393 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2395 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2396 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2398 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2400 hr = IDirect3DDevice9_EndScene(device);
2401 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2404 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2405 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2406 IDirect3DDevice9_SetVertexShader(device, NULL);
2407 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2409 IDirect3DVertexDeclaration9_Release(decl);
2410 IDirect3DVertexShader9_Release(shader);
2412 /* Z < 1.0 */
2413 color = getPixelColor(device, 28, 238);
2414 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2416 /* 1.0 < z < 0.75 */
2417 color = getPixelColor(device, 31, 238);
2418 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2419 color = getPixelColor(device, 100, 238);
2420 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2422 /* 0.75 < z < 0.0 */
2423 color = getPixelColor(device, 104, 238);
2424 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2425 color = getPixelColor(device, 318, 238);
2426 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2428 /* 0.0 < z */
2429 color = getPixelColor(device, 321, 238);
2430 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2432 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2433 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2435 out:
2436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2444 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2446 D3DSURFACE_DESC desc;
2447 D3DLOCKED_RECT l;
2448 HRESULT hr;
2449 unsigned int x, y;
2450 DWORD *mem;
2452 memset(&desc, 0, sizeof(desc));
2453 memset(&l, 0, sizeof(l));
2454 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2455 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2456 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2457 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2458 if(FAILED(hr)) return;
2460 for(y = 0; y < desc.Height; y++)
2462 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2463 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2465 mem[x] = color;
2468 hr = IDirect3DSurface9_UnlockRect(surface);
2469 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2472 /* This tests a variety of possible StretchRect() situations */
2473 static void stretchrect_test(IDirect3DDevice9 *device)
2475 HRESULT hr;
2476 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2477 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2478 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2479 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2480 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2481 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2482 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2483 IDirect3DSurface9 *orig_rt = NULL;
2484 IDirect3DSurface9 *backbuffer = NULL;
2485 DWORD color;
2487 RECT src_rect64 = {0, 0, 64, 64};
2488 RECT src_rect64_flipy = {0, 64, 64, 0};
2489 RECT dst_rect64 = {0, 0, 64, 64};
2490 RECT dst_rect64_flipy = {0, 64, 64, 0};
2492 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2493 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2494 if(!orig_rt) {
2495 goto out;
2498 /* Create our temporary surfaces in system memory */
2499 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2500 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2501 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2502 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2504 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2505 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2506 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2507 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2508 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2509 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2510 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2512 /* Create render target surfaces */
2513 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2514 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2515 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2516 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2517 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2518 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2519 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2520 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2522 /* Create render target textures */
2523 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2524 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2525 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2526 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2527 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2528 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2529 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2530 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2531 if (tex_rt32) {
2532 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2533 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2535 if (tex_rt64) {
2536 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2537 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2539 if (tex_rt_dest64) {
2540 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2541 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2543 if (tex_rt_dest64) {
2544 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2545 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2548 /* Create regular textures in D3DPOOL_DEFAULT */
2549 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2550 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2551 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2552 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2553 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2554 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2555 if (tex32) {
2556 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2557 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2559 if (tex64) {
2560 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2561 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2563 if (tex_dest64) {
2564 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2565 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2568 /*********************************************************************
2569 * Tests for when the source parameter is an offscreen plain surface *
2570 *********************************************************************/
2572 /* Fill the offscreen 64x64 surface with green */
2573 if (surf_offscreen64)
2574 fill_surface(surf_offscreen64, 0xff00ff00);
2576 /* offscreenplain ==> offscreenplain, same size */
2577 if(surf_offscreen64 && surf_offscreen_dest64) {
2578 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2579 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581 if (hr == D3D_OK) {
2582 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2583 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2586 /* Blit without scaling */
2587 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2588 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2591 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2592 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2595 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2596 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2599 /* offscreenplain ==> rendertarget texture, same size */
2600 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2601 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2602 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2604 /* We can't lock rendertarget textures, so copy to our temp surface first */
2605 if (hr == D3D_OK) {
2606 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2607 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2610 if (hr == D3D_OK) {
2611 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2612 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2615 /* Blit without scaling */
2616 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2617 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2619 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2620 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2621 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2623 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2624 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2625 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2628 /* offscreenplain ==> rendertarget surface, same size */
2629 if(surf_offscreen64 && surf_rt_dest64) {
2630 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2631 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2633 if (hr == D3D_OK) {
2634 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2635 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2638 /* Blit without scaling */
2639 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2640 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2643 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2644 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2646 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2647 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2648 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2651 /* offscreenplain ==> texture, same size (should fail) */
2652 if(surf_offscreen64 && surf_tex_dest64) {
2653 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2654 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2657 /* Fill the smaller offscreen surface with red */
2658 fill_surface(surf_offscreen32, 0xffff0000);
2660 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2661 if(surf_offscreen32 && surf_offscreen64) {
2662 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2663 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2666 /* offscreenplain ==> rendertarget texture, scaling */
2667 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2668 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2669 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2671 /* We can't lock rendertarget textures, so copy to our temp surface first */
2672 if (hr == D3D_OK) {
2673 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2674 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2677 if (hr == D3D_OK) {
2678 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2679 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2683 /* offscreenplain ==> rendertarget surface, scaling */
2684 if(surf_offscreen32 && surf_rt_dest64) {
2685 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2686 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2688 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2689 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2692 /* offscreenplain ==> texture, scaling (should fail) */
2693 if(surf_offscreen32 && surf_tex_dest64) {
2694 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2695 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2698 /************************************************************
2699 * Tests for when the source parameter is a regular texture *
2700 ************************************************************/
2702 /* Fill the surface of the regular texture with blue */
2703 if (surf_tex64 && surf_temp64) {
2704 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2705 fill_surface(surf_temp64, 0xff0000ff);
2706 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2707 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2710 /* texture ==> offscreenplain, same size */
2711 if(surf_tex64 && surf_offscreen64) {
2712 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2713 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2716 /* texture ==> rendertarget texture, same size */
2717 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2718 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2719 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2721 /* We can't lock rendertarget textures, so copy to our temp surface first */
2722 if (hr == D3D_OK) {
2723 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2724 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2727 if (hr == D3D_OK) {
2728 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2729 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2732 /* Blit without scaling */
2733 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2734 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2736 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2737 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2738 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2740 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2741 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2742 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2745 /* texture ==> rendertarget surface, same size */
2746 if(surf_tex64 && surf_rt_dest64) {
2747 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2748 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2750 if (hr == D3D_OK) {
2751 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2752 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2755 /* Blit without scaling */
2756 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2757 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2759 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2760 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2761 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2764 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2765 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2768 /* texture ==> texture, same size (should fail) */
2769 if(surf_tex64 && surf_tex_dest64) {
2770 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2771 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2774 /* Fill the surface of the smaller regular texture with red */
2775 if (surf_tex32 && surf_temp32) {
2776 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2777 fill_surface(surf_temp32, 0xffff0000);
2778 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2779 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2782 /* texture ==> offscreenplain, scaling (should fail) */
2783 if(surf_tex32 && surf_offscreen64) {
2784 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2785 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2788 /* texture ==> rendertarget texture, scaling */
2789 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2790 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2791 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793 /* We can't lock rendertarget textures, so copy to our temp surface first */
2794 if (hr == D3D_OK) {
2795 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2799 if (hr == D3D_OK) {
2800 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2801 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2805 /* texture ==> rendertarget surface, scaling */
2806 if(surf_tex32 && surf_rt_dest64) {
2807 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2808 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2810 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2811 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2814 /* texture ==> texture, scaling (should fail) */
2815 if(surf_tex32 && surf_tex_dest64) {
2816 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2817 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2820 /*****************************************************************
2821 * Tests for when the source parameter is a rendertarget texture *
2822 *****************************************************************/
2824 /* Fill the surface of the rendertarget texture with white */
2825 if (surf_tex_rt64 && surf_temp64) {
2826 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2827 fill_surface(surf_temp64, 0xffffffff);
2828 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2829 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2832 /* rendertarget texture ==> offscreenplain, same size */
2833 if(surf_tex_rt64 && surf_offscreen64) {
2834 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2835 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2838 /* rendertarget texture ==> rendertarget texture, same size */
2839 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2840 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2841 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2843 /* We can't lock rendertarget textures, so copy to our temp surface first */
2844 if (hr == D3D_OK) {
2845 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2846 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2849 if (hr == D3D_OK) {
2850 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2851 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2854 /* Blit without scaling */
2855 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2856 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2858 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2859 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2860 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2862 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2863 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2864 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2867 /* rendertarget texture ==> rendertarget surface, same size */
2868 if(surf_tex_rt64 && surf_rt_dest64) {
2869 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2870 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2872 if (hr == D3D_OK) {
2873 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2874 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2877 /* Blit without scaling */
2878 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2879 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2881 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2882 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2883 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2885 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2886 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2887 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2890 /* rendertarget texture ==> texture, same size (should fail) */
2891 if(surf_tex_rt64 && surf_tex_dest64) {
2892 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2893 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2896 /* Fill the surface of the smaller rendertarget texture with red */
2897 if (surf_tex_rt32 && surf_temp32) {
2898 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2899 fill_surface(surf_temp32, 0xffff0000);
2900 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2901 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2904 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2905 if(surf_tex_rt32 && surf_offscreen64) {
2906 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2907 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2910 /* rendertarget texture ==> rendertarget texture, scaling */
2911 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2912 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2913 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2915 /* We can't lock rendertarget textures, so copy to our temp surface first */
2916 if (hr == D3D_OK) {
2917 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2918 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2921 if (hr == D3D_OK) {
2922 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2923 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2927 /* rendertarget texture ==> rendertarget surface, scaling */
2928 if(surf_tex_rt32 && surf_rt_dest64) {
2929 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2930 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2932 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2933 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2936 /* rendertarget texture ==> texture, scaling (should fail) */
2937 if(surf_tex_rt32 && surf_tex_dest64) {
2938 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2939 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2942 /*****************************************************************
2943 * Tests for when the source parameter is a rendertarget surface *
2944 *****************************************************************/
2946 /* Fill the surface of the rendertarget surface with black */
2947 if (surf_rt64)
2948 fill_surface(surf_rt64, 0xff000000);
2950 /* rendertarget texture ==> offscreenplain, same size */
2951 if(surf_rt64 && surf_offscreen64) {
2952 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2953 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2956 /* rendertarget surface ==> rendertarget texture, same size */
2957 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2958 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2959 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2961 /* We can't lock rendertarget textures, so copy to our temp surface first */
2962 if (hr == D3D_OK) {
2963 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2964 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2967 if (hr == D3D_OK) {
2968 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2969 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2972 /* Blit without scaling */
2973 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2974 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2976 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2977 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2978 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2980 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2981 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2982 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2985 /* rendertarget surface ==> rendertarget surface, same size */
2986 if(surf_rt64 && surf_rt_dest64) {
2987 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2988 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2990 if (hr == D3D_OK) {
2991 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2992 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2995 /* Blit without scaling */
2996 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2997 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2999 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3000 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3001 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3003 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3004 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3005 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3008 /* rendertarget surface ==> texture, same size (should fail) */
3009 if(surf_rt64 && surf_tex_dest64) {
3010 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3011 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3014 /* Fill the surface of the smaller rendertarget texture with red */
3015 if (surf_rt32)
3016 fill_surface(surf_rt32, 0xffff0000);
3018 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3019 if(surf_rt32 && surf_offscreen64) {
3020 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3021 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3024 /* rendertarget surface ==> rendertarget texture, scaling */
3025 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3026 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3027 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3029 /* We can't lock rendertarget textures, so copy to our temp surface first */
3030 if (hr == D3D_OK) {
3031 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3032 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3035 if (hr == D3D_OK) {
3036 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3037 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3041 /* rendertarget surface ==> rendertarget surface, scaling */
3042 if(surf_rt32 && surf_rt_dest64) {
3043 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3044 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3046 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3047 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3050 /* rendertarget surface ==> texture, scaling (should fail) */
3051 if(surf_rt32 && surf_tex_dest64) {
3052 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3053 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3056 /* backbuffer ==> surface tests (no scaling) */
3057 if(backbuffer && surf_tex_rt_dest640_480)
3059 RECT src_rect = {0, 0, 640, 480};
3060 RECT src_rect_flipy = {0, 480, 640, 0};
3061 RECT dst_rect = {0, 0, 640, 480};
3062 RECT dst_rect_flipy = {0, 480, 640, 0};
3064 /* Blit with NULL rectangles */
3065 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3066 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3068 /* Blit without scaling */
3069 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3070 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3072 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3073 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3074 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3076 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3077 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3078 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3081 /* TODO: Test format conversions */
3084 out:
3085 /* Clean up */
3086 if (backbuffer)
3087 IDirect3DSurface9_Release(backbuffer);
3088 if (surf_rt32)
3089 IDirect3DSurface9_Release(surf_rt32);
3090 if (surf_rt64)
3091 IDirect3DSurface9_Release(surf_rt64);
3092 if (surf_rt_dest64)
3093 IDirect3DSurface9_Release(surf_rt_dest64);
3094 if (surf_temp32)
3095 IDirect3DSurface9_Release(surf_temp32);
3096 if (surf_temp64)
3097 IDirect3DSurface9_Release(surf_temp64);
3098 if (surf_offscreen32)
3099 IDirect3DSurface9_Release(surf_offscreen32);
3100 if (surf_offscreen64)
3101 IDirect3DSurface9_Release(surf_offscreen64);
3102 if (surf_offscreen_dest64)
3103 IDirect3DSurface9_Release(surf_offscreen_dest64);
3105 if (tex_rt32) {
3106 if (surf_tex_rt32)
3107 IDirect3DSurface9_Release(surf_tex_rt32);
3108 IDirect3DTexture9_Release(tex_rt32);
3110 if (tex_rt64) {
3111 if (surf_tex_rt64)
3112 IDirect3DSurface9_Release(surf_tex_rt64);
3113 IDirect3DTexture9_Release(tex_rt64);
3115 if (tex_rt_dest64) {
3116 if (surf_tex_rt_dest64)
3117 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3118 IDirect3DTexture9_Release(tex_rt_dest64);
3120 if (tex_rt_dest640_480) {
3121 if (surf_tex_rt_dest640_480)
3122 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3123 IDirect3DTexture9_Release(tex_rt_dest640_480);
3125 if (tex32) {
3126 if (surf_tex32)
3127 IDirect3DSurface9_Release(surf_tex32);
3128 IDirect3DTexture9_Release(tex32);
3130 if (tex64) {
3131 if (surf_tex64)
3132 IDirect3DSurface9_Release(surf_tex64);
3133 IDirect3DTexture9_Release(tex64);
3135 if (tex_dest64) {
3136 if (surf_tex_dest64)
3137 IDirect3DSurface9_Release(surf_tex_dest64);
3138 IDirect3DTexture9_Release(tex_dest64);
3141 if (orig_rt) {
3142 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3143 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3144 IDirect3DSurface9_Release(orig_rt);
3148 static void maxmip_test(IDirect3DDevice9 *device)
3150 IDirect3DTexture9 *texture = NULL;
3151 IDirect3DSurface9 *surface = NULL;
3152 HRESULT hr;
3153 DWORD color;
3154 static const struct
3156 struct
3158 float x, y, z;
3159 float s, t;
3161 v[4];
3163 quads[] =
3166 {-1.0, -1.0, 0.0, 0.0, 0.0},
3167 {-1.0, 0.0, 0.0, 0.0, 1.0},
3168 { 0.0, -1.0, 0.0, 1.0, 0.0},
3169 { 0.0, 0.0, 0.0, 1.0, 1.0},
3172 { 0.0, -1.0, 0.0, 0.0, 0.0},
3173 { 0.0, 0.0, 0.0, 0.0, 1.0},
3174 { 1.0, -1.0, 0.0, 1.0, 0.0},
3175 { 1.0, 0.0, 0.0, 1.0, 1.0},
3178 { 0.0, 0.0, 0.0, 0.0, 0.0},
3179 { 0.0, 1.0, 0.0, 0.0, 1.0},
3180 { 1.0, 0.0, 0.0, 1.0, 0.0},
3181 { 1.0, 1.0, 0.0, 1.0, 1.0},
3184 {-1.0, 0.0, 0.0, 0.0, 0.0},
3185 {-1.0, 1.0, 0.0, 0.0, 1.0},
3186 { 0.0, 0.0, 0.0, 1.0, 0.0},
3187 { 0.0, 1.0, 0.0, 1.0, 1.0},
3191 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3192 &texture, NULL);
3193 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3194 if(!texture)
3196 skip("Failed to create test texture\n");
3197 return;
3200 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3201 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3202 fill_surface(surface, 0xffff0000);
3203 IDirect3DSurface9_Release(surface);
3204 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3205 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3206 fill_surface(surface, 0xff00ff00);
3207 IDirect3DSurface9_Release(surface);
3208 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3209 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3210 fill_surface(surface, 0xff0000ff);
3211 IDirect3DSurface9_Release(surface);
3213 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3214 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3215 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3216 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3218 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3219 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3222 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3224 hr = IDirect3DDevice9_BeginScene(device);
3225 if(SUCCEEDED(hr))
3227 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3228 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3230 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3232 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3233 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3235 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3238 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3240 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3243 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3245 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3246 hr = IDirect3DDevice9_EndScene(device);
3247 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3250 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3251 color = getPixelColor(device, 160, 360);
3252 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3253 color = getPixelColor(device, 480, 360);
3254 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3255 color = getPixelColor(device, 480, 120);
3256 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3257 color = getPixelColor(device, 160, 120);
3258 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3259 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3260 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3262 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3266 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3268 hr = IDirect3DDevice9_BeginScene(device);
3269 if(SUCCEEDED(hr))
3271 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3272 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3274 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3276 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3277 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3279 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3281 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3282 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3284 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3286 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3287 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3289 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3290 hr = IDirect3DDevice9_EndScene(device);
3291 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3294 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3295 * level 3 (> levels in texture) samples from the highest level in the
3296 * texture (level 2). */
3297 color = getPixelColor(device, 160, 360);
3298 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3299 color = getPixelColor(device, 480, 360);
3300 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3301 color = getPixelColor(device, 480, 120);
3302 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3303 color = getPixelColor(device, 160, 120);
3304 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3305 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3306 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3308 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3311 hr = IDirect3DDevice9_BeginScene(device);
3312 if(SUCCEEDED(hr))
3314 DWORD ret;
3316 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3317 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3318 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3319 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3320 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3321 ret = IDirect3DTexture9_SetLOD(texture, 1);
3322 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3324 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3326 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3327 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3328 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3329 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3330 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3331 ret = IDirect3DTexture9_SetLOD(texture, 2);
3332 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3333 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3334 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3336 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3337 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3338 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3339 ret = IDirect3DTexture9_SetLOD(texture, 1);
3340 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3341 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3342 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3344 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3345 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3346 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3347 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3348 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3349 ret = IDirect3DTexture9_SetLOD(texture, 1);
3350 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3352 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3353 hr = IDirect3DDevice9_EndScene(device);
3354 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3357 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3358 * level 3 (> levels in texture) samples from the highest level in the
3359 * texture (level 2). */
3360 color = getPixelColor(device, 160, 360);
3361 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3362 color = getPixelColor(device, 480, 360);
3363 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3364 color = getPixelColor(device, 480, 120);
3365 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3366 color = getPixelColor(device, 160, 120);
3367 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3369 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3370 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3372 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3373 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3374 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3375 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3376 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3377 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3378 IDirect3DTexture9_Release(texture);
3381 static void release_buffer_test(IDirect3DDevice9 *device)
3383 IDirect3DVertexBuffer9 *vb = NULL;
3384 IDirect3DIndexBuffer9 *ib = NULL;
3385 HRESULT hr;
3386 BYTE *data;
3387 LONG ref;
3389 static const struct vertex quad[] = {
3390 {-1.0, -1.0, 0.1, 0xffff0000},
3391 {-1.0, 1.0, 0.1, 0xffff0000},
3392 { 1.0, 1.0, 0.1, 0xffff0000},
3394 {-1.0, -1.0, 0.1, 0xff00ff00},
3395 {-1.0, 1.0, 0.1, 0xff00ff00},
3396 { 1.0, 1.0, 0.1, 0xff00ff00}
3398 short indices[] = {3, 4, 5};
3400 /* Index and vertex buffers should always be creatable */
3401 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3402 D3DPOOL_MANAGED, &vb, NULL);
3403 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3404 if(!vb) {
3405 skip("Failed to create a vertex buffer\n");
3406 return;
3408 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3409 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3410 if(!ib) {
3411 skip("Failed to create an index buffer\n");
3412 return;
3415 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3416 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3417 memcpy(data, quad, sizeof(quad));
3418 hr = IDirect3DVertexBuffer9_Unlock(vb);
3419 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3421 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3422 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3423 memcpy(data, indices, sizeof(indices));
3424 hr = IDirect3DIndexBuffer9_Unlock(ib);
3425 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3427 hr = IDirect3DDevice9_SetIndices(device, ib);
3428 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3429 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3430 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3431 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3432 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3434 /* Now destroy the bound index buffer and draw again */
3435 ref = IDirect3DIndexBuffer9_Release(ib);
3436 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3438 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3439 ok(hr == D3D_OK, "IDirect3DDevice9_Clear 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 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3446 * making assumptions about the indices or vertices
3448 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3449 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3450 hr = IDirect3DDevice9_EndScene(device);
3451 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3454 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3455 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3457 hr = IDirect3DDevice9_SetIndices(device, NULL);
3458 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3459 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3460 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3462 /* Index buffer was already destroyed as part of the test */
3463 IDirect3DVertexBuffer9_Release(vb);
3466 static void float_texture_test(IDirect3DDevice9 *device)
3468 IDirect3D9 *d3d = NULL;
3469 HRESULT hr;
3470 IDirect3DTexture9 *texture = NULL;
3471 D3DLOCKED_RECT lr;
3472 float *data;
3473 DWORD color;
3474 float quad[] = {
3475 -1.0, -1.0, 0.1, 0.0, 0.0,
3476 -1.0, 1.0, 0.1, 0.0, 1.0,
3477 1.0, -1.0, 0.1, 1.0, 0.0,
3478 1.0, 1.0, 0.1, 1.0, 1.0,
3481 memset(&lr, 0, sizeof(lr));
3482 IDirect3DDevice9_GetDirect3D(device, &d3d);
3483 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3484 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3485 skip("D3DFMT_R32F textures not supported\n");
3486 goto out;
3489 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3490 D3DPOOL_MANAGED, &texture, NULL);
3491 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3492 if(!texture) {
3493 skip("Failed to create R32F texture\n");
3494 goto out;
3497 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3498 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3499 data = lr.pBits;
3500 *data = 0.0;
3501 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3502 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3504 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3507 hr = IDirect3DDevice9_BeginScene(device);
3508 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3509 if(SUCCEEDED(hr))
3511 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3512 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3515 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3517 hr = IDirect3DDevice9_EndScene(device);
3518 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3520 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3521 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3523 color = getPixelColor(device, 240, 320);
3524 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3526 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3527 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3529 out:
3530 if(texture) IDirect3DTexture9_Release(texture);
3531 IDirect3D9_Release(d3d);
3534 static void g16r16_texture_test(IDirect3DDevice9 *device)
3536 IDirect3D9 *d3d = NULL;
3537 HRESULT hr;
3538 IDirect3DTexture9 *texture = NULL;
3539 D3DLOCKED_RECT lr;
3540 DWORD *data;
3541 DWORD color;
3542 float quad[] = {
3543 -1.0, -1.0, 0.1, 0.0, 0.0,
3544 -1.0, 1.0, 0.1, 0.0, 1.0,
3545 1.0, -1.0, 0.1, 1.0, 0.0,
3546 1.0, 1.0, 0.1, 1.0, 1.0,
3549 memset(&lr, 0, sizeof(lr));
3550 IDirect3DDevice9_GetDirect3D(device, &d3d);
3551 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3552 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3553 skip("D3DFMT_G16R16 textures not supported\n");
3554 goto out;
3557 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3558 D3DPOOL_MANAGED, &texture, NULL);
3559 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3560 if(!texture) {
3561 skip("Failed to create D3DFMT_G16R16 texture\n");
3562 goto out;
3565 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3566 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3567 data = lr.pBits;
3568 *data = 0x0f00f000;
3569 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3570 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3572 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3573 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3575 hr = IDirect3DDevice9_BeginScene(device);
3576 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3577 if(SUCCEEDED(hr))
3579 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3580 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3583 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3585 hr = IDirect3DDevice9_EndScene(device);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3588 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3589 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3591 color = getPixelColor(device, 240, 320);
3592 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3593 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3596 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3598 out:
3599 if(texture) IDirect3DTexture9_Release(texture);
3600 IDirect3D9_Release(d3d);
3603 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3605 HRESULT hr;
3606 IDirect3D9 *d3d;
3607 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3608 D3DCAPS9 caps;
3609 IDirect3DTexture9 *texture = NULL;
3610 IDirect3DVolumeTexture9 *volume = NULL;
3611 unsigned int x, y, z;
3612 D3DLOCKED_RECT lr;
3613 D3DLOCKED_BOX lb;
3614 DWORD color;
3615 UINT w, h;
3616 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3617 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3618 0.0, 1.0, 0.0, 0.0,
3619 0.0, 0.0, 1.0, 0.0,
3620 0.0, 0.0, 0.0, 1.0};
3621 static const D3DVERTEXELEMENT9 decl_elements[] = {
3622 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3623 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3624 D3DDECL_END()
3626 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3627 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3628 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3629 D3DDECL_END()
3631 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3632 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3633 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3634 D3DDECL_END()
3636 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3637 0x00, 0xff, 0x00, 0x00,
3638 0x00, 0x00, 0x00, 0x00,
3639 0x00, 0x00, 0x00, 0x00};
3641 memset(&lr, 0, sizeof(lr));
3642 memset(&lb, 0, sizeof(lb));
3643 IDirect3DDevice9_GetDirect3D(device, &d3d);
3644 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3645 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3646 fmt = D3DFMT_A16B16G16R16;
3648 IDirect3D9_Release(d3d);
3650 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3651 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3652 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3653 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3654 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3656 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3657 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3658 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3659 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3660 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3661 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3662 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3664 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3665 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3666 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3667 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3668 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3669 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3671 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3672 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3673 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3675 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3676 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3677 w = min(1024, caps.MaxTextureWidth);
3678 h = min(1024, caps.MaxTextureHeight);
3679 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3680 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3681 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3682 if(!texture) {
3683 skip("Failed to create the test texture\n");
3684 return;
3687 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3688 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3689 * 1.0 in red and green for the x and y coords
3691 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3692 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3693 for(y = 0; y < h; y++) {
3694 for(x = 0; x < w; x++) {
3695 double r_f = (double) y / (double) h;
3696 double g_f = (double) x / (double) w;
3697 if(fmt == D3DFMT_A16B16G16R16) {
3698 unsigned short r, g;
3699 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3700 r = (unsigned short) (r_f * 65536.0);
3701 g = (unsigned short) (g_f * 65536.0);
3702 dst[0] = r;
3703 dst[1] = g;
3704 dst[2] = 0;
3705 dst[3] = 65535;
3706 } else {
3707 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3708 unsigned char r = (unsigned char) (r_f * 255.0);
3709 unsigned char g = (unsigned char) (g_f * 255.0);
3710 dst[0] = 0;
3711 dst[1] = g;
3712 dst[2] = r;
3713 dst[3] = 255;
3717 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3718 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3719 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3720 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3722 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3724 hr = IDirect3DDevice9_BeginScene(device);
3725 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3726 if(SUCCEEDED(hr))
3728 float quad1[] = {
3729 -1.0, -1.0, 0.1, 1.0, 1.0,
3730 -1.0, 0.0, 0.1, 1.0, 1.0,
3731 0.0, -1.0, 0.1, 1.0, 1.0,
3732 0.0, 0.0, 0.1, 1.0, 1.0,
3734 float quad2[] = {
3735 -1.0, 0.0, 0.1, 1.0, 1.0,
3736 -1.0, 1.0, 0.1, 1.0, 1.0,
3737 0.0, 0.0, 0.1, 1.0, 1.0,
3738 0.0, 1.0, 0.1, 1.0, 1.0,
3740 float quad3[] = {
3741 0.0, 0.0, 0.1, 0.5, 0.5,
3742 0.0, 1.0, 0.1, 0.5, 0.5,
3743 1.0, 0.0, 0.1, 0.5, 0.5,
3744 1.0, 1.0, 0.1, 0.5, 0.5,
3746 float quad4[] = {
3747 320, 480, 0.1, 1.0, 0.0, 1.0,
3748 320, 240, 0.1, 1.0, 0.0, 1.0,
3749 640, 480, 0.1, 1.0, 0.0, 1.0,
3750 640, 240, 0.1, 1.0, 0.0, 1.0,
3752 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3753 0.0, 0.0, 0.0, 0.0,
3754 0.0, 0.0, 0.0, 0.0,
3755 0.0, 0.0, 0.0, 0.0};
3757 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3758 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3759 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3761 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3763 /* What happens with transforms enabled? */
3764 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3765 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3767 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3769 /* What happens if 4 coords are used, but only 2 given ?*/
3770 mat[8] = 1.0;
3771 mat[13] = 1.0;
3772 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3774 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3775 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3777 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3779 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3780 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3781 * due to the coords in the vertices. (turns out red, indeed)
3783 memset(mat, 0, sizeof(mat));
3784 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3785 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3786 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3787 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3788 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3791 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3793 hr = IDirect3DDevice9_EndScene(device);
3794 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3796 color = getPixelColor(device, 160, 360);
3797 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3798 color = getPixelColor(device, 160, 120);
3799 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3800 color = getPixelColor(device, 480, 120);
3801 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3802 color = getPixelColor(device, 480, 360);
3803 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3805 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3807 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3808 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3810 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3811 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3812 hr = IDirect3DDevice9_BeginScene(device);
3813 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3814 if(SUCCEEDED(hr))
3816 float quad1[] = {
3817 -1.0, -1.0, 0.1, 0.8, 0.2,
3818 -1.0, 0.0, 0.1, 0.8, 0.2,
3819 0.0, -1.0, 0.1, 0.8, 0.2,
3820 0.0, 0.0, 0.1, 0.8, 0.2,
3822 float quad2[] = {
3823 -1.0, 0.0, 0.1, 0.5, 1.0,
3824 -1.0, 1.0, 0.1, 0.5, 1.0,
3825 0.0, 0.0, 0.1, 0.5, 1.0,
3826 0.0, 1.0, 0.1, 0.5, 1.0,
3828 float quad3[] = {
3829 0.0, 0.0, 0.1, 0.5, 1.0,
3830 0.0, 1.0, 0.1, 0.5, 1.0,
3831 1.0, 0.0, 0.1, 0.5, 1.0,
3832 1.0, 1.0, 0.1, 0.5, 1.0,
3834 float quad4[] = {
3835 0.0, -1.0, 0.1, 0.8, 0.2,
3836 0.0, 0.0, 0.1, 0.8, 0.2,
3837 1.0, -1.0, 0.1, 0.8, 0.2,
3838 1.0, 0.0, 0.1, 0.8, 0.2,
3840 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3841 0.0, 0.0, 0.0, 0.0,
3842 0.0, 1.0, 0.0, 0.0,
3843 0.0, 0.0, 0.0, 0.0};
3845 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3847 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3848 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3849 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3850 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3853 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3855 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3856 * it behaves like COUNT2 because normal textures require 2 coords
3858 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3859 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3861 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3863 /* Just to be sure, the same as quad2 above */
3864 memset(mat, 0, sizeof(mat));
3865 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3866 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3867 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3868 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3870 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3872 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3873 * used? And what happens to the first?
3875 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3876 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3878 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3880 hr = IDirect3DDevice9_EndScene(device);
3881 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3883 color = getPixelColor(device, 160, 360);
3884 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3885 color = getPixelColor(device, 160, 120);
3886 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3887 color = getPixelColor(device, 480, 120);
3888 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3889 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3890 color = getPixelColor(device, 480, 360);
3891 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3892 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3894 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3896 IDirect3DTexture9_Release(texture);
3898 /* Test projected textures, without any fancy matrices */
3899 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3900 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3901 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3902 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3903 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3905 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3906 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3908 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3909 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3910 for(x = 0; x < 4; x++) {
3911 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3913 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3914 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3915 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3916 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3918 hr = IDirect3DDevice9_BeginScene(device);
3919 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3920 if(SUCCEEDED(hr))
3922 const float proj_quads[] = {
3923 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3924 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3925 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3926 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3927 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3928 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3929 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3930 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3933 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3934 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3935 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3936 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3938 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3939 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3941 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3943 hr = IDirect3DDevice9_EndScene(device);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3947 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3948 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3949 IDirect3DTexture9_Release(texture);
3951 color = getPixelColor(device, 158, 118);
3952 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3953 color = getPixelColor(device, 162, 118);
3954 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3955 color = getPixelColor(device, 158, 122);
3956 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3957 color = getPixelColor(device, 162, 122);
3958 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3960 color = getPixelColor(device, 158, 178);
3961 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3962 color = getPixelColor(device, 162, 178);
3963 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3964 color = getPixelColor(device, 158, 182);
3965 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3966 color = getPixelColor(device, 162, 182);
3967 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3969 color = getPixelColor(device, 318, 118);
3970 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3971 color = getPixelColor(device, 322, 118);
3972 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3973 color = getPixelColor(device, 318, 122);
3974 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3975 color = getPixelColor(device, 322, 122);
3976 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3978 color = getPixelColor(device, 318, 178);
3979 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3980 color = getPixelColor(device, 322, 178);
3981 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3982 color = getPixelColor(device, 318, 182);
3983 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3984 color = getPixelColor(device, 322, 182);
3985 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3987 color = getPixelColor(device, 238, 298);
3988 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3989 color = getPixelColor(device, 242, 298);
3990 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3991 color = getPixelColor(device, 238, 302);
3992 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3993 color = getPixelColor(device, 242, 302);
3994 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3996 color = getPixelColor(device, 238, 388);
3997 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3998 color = getPixelColor(device, 242, 388);
3999 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4000 color = getPixelColor(device, 238, 392);
4001 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
4002 color = getPixelColor(device, 242, 392);
4003 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
4005 color = getPixelColor(device, 478, 298);
4006 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
4007 color = getPixelColor(device, 482, 298);
4008 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
4009 color = getPixelColor(device, 478, 302);
4010 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
4011 color = getPixelColor(device, 482, 302);
4012 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
4014 color = getPixelColor(device, 478, 388);
4015 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4016 color = getPixelColor(device, 482, 388);
4017 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
4018 color = getPixelColor(device, 478, 392);
4019 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
4020 color = getPixelColor(device, 482, 392);
4021 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
4023 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4026 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4027 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4028 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4029 * Thus watch out if sampling from texels between 0 and 1.
4031 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4032 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4033 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4034 if(!volume) {
4035 skip("Failed to create a volume texture\n");
4036 goto out;
4039 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4040 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4041 for(z = 0; z < 32; z++) {
4042 for(y = 0; y < 32; y++) {
4043 for(x = 0; x < 32; x++) {
4044 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4045 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4046 float r_f = (float) x / 31.0;
4047 float g_f = (float) y / 31.0;
4048 float b_f = (float) z / 31.0;
4050 if(fmt == D3DFMT_A16B16G16R16) {
4051 unsigned short *mem_s = mem;
4052 mem_s[0] = r_f * 65535.0;
4053 mem_s[1] = g_f * 65535.0;
4054 mem_s[2] = b_f * 65535.0;
4055 mem_s[3] = 65535;
4056 } else {
4057 unsigned char *mem_c = mem;
4058 mem_c[0] = b_f * 255.0;
4059 mem_c[1] = g_f * 255.0;
4060 mem_c[2] = r_f * 255.0;
4061 mem_c[3] = 255;
4066 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4067 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4069 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4070 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4072 hr = IDirect3DDevice9_BeginScene(device);
4073 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4074 if(SUCCEEDED(hr))
4076 float quad1[] = {
4077 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4078 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4079 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4080 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4082 float quad2[] = {
4083 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4084 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4085 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4086 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4088 float quad3[] = {
4089 0.0, 0.0, 0.1, 0.0, 0.0,
4090 0.0, 1.0, 0.1, 0.0, 0.0,
4091 1.0, 0.0, 0.1, 0.0, 0.0,
4092 1.0, 1.0, 0.1, 0.0, 0.0
4094 float quad4[] = {
4095 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4096 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4097 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4098 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4100 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4101 0.0, 0.0, 1.0, 0.0,
4102 0.0, 1.0, 0.0, 0.0,
4103 0.0, 0.0, 0.0, 1.0};
4104 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4105 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4107 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4108 * values
4110 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4111 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4112 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4113 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4114 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4115 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4117 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4118 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4119 * otherwise the w will be missing(blue).
4120 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4121 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4123 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4124 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4126 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4128 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4129 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4130 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4131 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4132 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4133 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4136 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4138 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4139 * disable. ATI extends it up to the amount of values needed for the volume texture
4141 memset(mat, 0, sizeof(mat));
4142 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4143 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4144 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4145 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4146 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4149 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4151 hr = IDirect3DDevice9_EndScene(device);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4155 color = getPixelColor(device, 160, 360);
4156 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4157 color = getPixelColor(device, 160, 120);
4158 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4159 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4160 color = getPixelColor(device, 480, 120);
4161 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4162 color = getPixelColor(device, 480, 360);
4163 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4165 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4168 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4169 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4170 hr = IDirect3DDevice9_BeginScene(device);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4172 if(SUCCEEDED(hr))
4174 float quad1[] = {
4175 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4176 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4177 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4178 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4180 float quad2[] = {
4181 -1.0, 0.0, 0.1,
4182 -1.0, 1.0, 0.1,
4183 0.0, 0.0, 0.1,
4184 0.0, 1.0, 0.1,
4186 float quad3[] = {
4187 0.0, 0.0, 0.1, 1.0,
4188 0.0, 1.0, 0.1, 1.0,
4189 1.0, 0.0, 0.1, 1.0,
4190 1.0, 1.0, 0.1, 1.0
4192 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4193 0.0, 0.0, 0.0, 0.0,
4194 0.0, 0.0, 0.0, 0.0,
4195 0.0, 1.0, 0.0, 0.0};
4196 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4197 1.0, 0.0, 0.0, 0.0,
4198 0.0, 1.0, 0.0, 0.0,
4199 0.0, 0.0, 1.0, 0.0};
4200 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4201 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4203 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4204 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4205 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4206 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4207 * 4th *input* coordinate.
4209 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4210 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4211 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4212 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4214 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4216 /* None passed */
4217 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4218 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4219 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4220 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4221 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4222 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4224 /* 4 used, 1 passed */
4225 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4227 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4228 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4230 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4232 hr = IDirect3DDevice9_EndScene(device);
4233 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4235 color = getPixelColor(device, 160, 360);
4236 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4237 color = getPixelColor(device, 160, 120);
4238 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4239 color = getPixelColor(device, 480, 120);
4240 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4241 /* Quad4: unused */
4243 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4246 IDirect3DVolumeTexture9_Release(volume);
4248 out:
4249 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4250 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4251 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4253 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4254 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4255 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4256 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4257 IDirect3DVertexDeclaration9_Release(decl);
4258 IDirect3DVertexDeclaration9_Release(decl2);
4259 IDirect3DVertexDeclaration9_Release(decl3);
4262 static void texdepth_test(IDirect3DDevice9 *device)
4264 IDirect3DPixelShader9 *shader;
4265 HRESULT hr;
4266 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4267 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4268 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4269 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4270 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4271 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4272 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4273 DWORD shader_code[] = {
4274 0xffff0104, /* ps_1_4 */
4275 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4276 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4277 0x0000fffd, /* phase */
4278 0x00000057, 0x800f0005, /* texdepth r5 */
4279 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4280 0x0000ffff /* end */
4282 DWORD color;
4283 float vertex[] = {
4284 -1.0, -1.0, 0.0,
4285 1.0, -1.0, 1.0,
4286 -1.0, 1.0, 0.0,
4287 1.0, 1.0, 1.0
4290 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4291 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4294 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4296 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4301 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4302 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4304 /* Fill the depth buffer with a gradient */
4305 hr = IDirect3DDevice9_BeginScene(device);
4306 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4307 if(SUCCEEDED(hr))
4309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4310 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4311 hr = IDirect3DDevice9_EndScene(device);
4312 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4315 /* Now perform the actual tests. Same geometry, but with the shader */
4316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4320 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4321 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4323 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4324 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4325 hr = IDirect3DDevice9_BeginScene(device);
4326 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4327 if(SUCCEEDED(hr))
4329 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4330 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4332 hr = IDirect3DDevice9_EndScene(device);
4333 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4336 color = getPixelColor(device, 158, 240);
4337 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4338 color = getPixelColor(device, 162, 240);
4339 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4341 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4342 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4344 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4345 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4347 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4348 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4349 hr = IDirect3DDevice9_BeginScene(device);
4350 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4351 if(SUCCEEDED(hr))
4353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4354 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4356 hr = IDirect3DDevice9_EndScene(device);
4357 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4360 color = getPixelColor(device, 318, 240);
4361 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4362 color = getPixelColor(device, 322, 240);
4363 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4366 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4368 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4369 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4371 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4372 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4373 hr = IDirect3DDevice9_BeginScene(device);
4374 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4375 if(SUCCEEDED(hr))
4377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4378 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4380 hr = IDirect3DDevice9_EndScene(device);
4381 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4384 color = getPixelColor(device, 1, 240);
4385 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4387 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4388 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4391 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4393 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4395 hr = IDirect3DDevice9_BeginScene(device);
4396 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4397 if(SUCCEEDED(hr))
4399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4400 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4402 hr = IDirect3DDevice9_EndScene(device);
4403 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4405 color = getPixelColor(device, 318, 240);
4406 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4407 color = getPixelColor(device, 322, 240);
4408 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4410 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4411 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4414 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4416 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4418 hr = IDirect3DDevice9_BeginScene(device);
4419 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4420 if(SUCCEEDED(hr))
4422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4423 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4425 hr = IDirect3DDevice9_EndScene(device);
4426 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4429 color = getPixelColor(device, 1, 240);
4430 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4432 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4436 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4438 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4439 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4440 hr = IDirect3DDevice9_BeginScene(device);
4441 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4442 if(SUCCEEDED(hr))
4444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4445 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447 hr = IDirect3DDevice9_EndScene(device);
4448 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4451 color = getPixelColor(device, 638, 240);
4452 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4454 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4455 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4457 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4458 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4460 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4461 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4462 hr = IDirect3DDevice9_BeginScene(device);
4463 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4464 if(SUCCEEDED(hr))
4466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4467 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4469 hr = IDirect3DDevice9_EndScene(device);
4470 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4473 color = getPixelColor(device, 638, 240);
4474 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4476 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4477 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4479 /* Cleanup */
4480 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4481 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4482 IDirect3DPixelShader9_Release(shader);
4484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4485 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4487 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4490 static void texkill_test(IDirect3DDevice9 *device)
4492 IDirect3DPixelShader9 *shader;
4493 HRESULT hr;
4494 DWORD color;
4496 const float vertex[] = {
4497 /* bottom top right left */
4498 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4499 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4500 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4501 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4504 DWORD shader_code_11[] = {
4505 0xffff0101, /* ps_1_1 */
4506 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4507 0x00000041, 0xb00f0000, /* texkill t0 */
4508 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4509 0x0000ffff /* end */
4511 DWORD shader_code_20[] = {
4512 0xffff0200, /* ps_2_0 */
4513 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4514 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4515 0x01000041, 0xb00f0000, /* texkill t0 */
4516 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4517 0x0000ffff /* end */
4520 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4521 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4522 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4523 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4525 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4526 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4527 hr = IDirect3DDevice9_BeginScene(device);
4528 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4529 if(SUCCEEDED(hr))
4531 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4532 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4534 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4535 hr = IDirect3DDevice9_EndScene(device);
4536 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4538 color = getPixelColor(device, 63, 46);
4539 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4540 color = getPixelColor(device, 66, 46);
4541 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4542 color = getPixelColor(device, 63, 49);
4543 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4544 color = getPixelColor(device, 66, 49);
4545 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4547 color = getPixelColor(device, 578, 46);
4548 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4549 color = getPixelColor(device, 575, 46);
4550 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4551 color = getPixelColor(device, 578, 49);
4552 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4553 color = getPixelColor(device, 575, 49);
4554 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4556 color = getPixelColor(device, 63, 430);
4557 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4558 color = getPixelColor(device, 63, 433);
4559 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4560 color = getPixelColor(device, 66, 433);
4561 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4562 color = getPixelColor(device, 66, 430);
4563 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4565 color = getPixelColor(device, 578, 430);
4566 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4567 color = getPixelColor(device, 578, 433);
4568 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4569 color = getPixelColor(device, 575, 433);
4570 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4571 color = getPixelColor(device, 575, 430);
4572 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4574 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4575 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4577 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4578 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4579 IDirect3DPixelShader9_Release(shader);
4581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4582 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4583 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4584 if(FAILED(hr)) {
4585 skip("Failed to create 2.0 test shader, most likely not supported\n");
4586 return;
4589 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4590 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4591 hr = IDirect3DDevice9_BeginScene(device);
4592 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4593 if(SUCCEEDED(hr))
4595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4596 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4597 hr = IDirect3DDevice9_EndScene(device);
4598 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4601 color = getPixelColor(device, 63, 46);
4602 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4603 color = getPixelColor(device, 66, 46);
4604 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4605 color = getPixelColor(device, 63, 49);
4606 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4607 color = getPixelColor(device, 66, 49);
4608 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4610 color = getPixelColor(device, 578, 46);
4611 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4612 color = getPixelColor(device, 575, 46);
4613 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4614 color = getPixelColor(device, 578, 49);
4615 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4616 color = getPixelColor(device, 575, 49);
4617 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4619 color = getPixelColor(device, 63, 430);
4620 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4621 color = getPixelColor(device, 63, 433);
4622 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4623 color = getPixelColor(device, 66, 433);
4624 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4625 color = getPixelColor(device, 66, 430);
4626 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4628 color = getPixelColor(device, 578, 430);
4629 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4630 color = getPixelColor(device, 578, 433);
4631 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4632 color = getPixelColor(device, 575, 433);
4633 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4634 color = getPixelColor(device, 575, 430);
4635 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4637 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4638 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4640 /* Cleanup */
4641 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4642 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4643 IDirect3DPixelShader9_Release(shader);
4646 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4648 IDirect3D9 *d3d9;
4649 HRESULT hr;
4650 IDirect3DTexture9 *texture;
4651 IDirect3DPixelShader9 *shader;
4652 IDirect3DPixelShader9 *shader2;
4653 D3DLOCKED_RECT lr;
4654 DWORD color;
4655 DWORD shader_code[] = {
4656 0xffff0101, /* ps_1_1 */
4657 0x00000042, 0xb00f0000, /* tex t0 */
4658 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4659 0x0000ffff /* end */
4661 DWORD shader_code2[] = {
4662 0xffff0101, /* ps_1_1 */
4663 0x00000042, 0xb00f0000, /* tex t0 */
4664 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4665 0x0000ffff /* end */
4668 float quad[] = {
4669 -1.0, -1.0, 0.1, 0.5, 0.5,
4670 1.0, -1.0, 0.1, 0.5, 0.5,
4671 -1.0, 1.0, 0.1, 0.5, 0.5,
4672 1.0, 1.0, 0.1, 0.5, 0.5,
4675 memset(&lr, 0, sizeof(lr));
4676 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4677 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4678 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4679 IDirect3D9_Release(d3d9);
4680 if(FAILED(hr)) {
4681 skip("No D3DFMT_X8L8V8U8 support\n");
4682 return;
4685 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4686 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4688 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4689 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4690 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4691 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4692 *((DWORD *) lr.pBits) = 0x11ca3141;
4693 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4694 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4696 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4697 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4698 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4699 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4702 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4703 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4704 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4705 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4706 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4708 hr = IDirect3DDevice9_BeginScene(device);
4709 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4710 if(SUCCEEDED(hr))
4712 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4713 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4715 hr = IDirect3DDevice9_EndScene(device);
4716 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4718 color = getPixelColor(device, 578, 430);
4719 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4720 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4721 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4722 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4724 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4725 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4726 hr = IDirect3DDevice9_BeginScene(device);
4727 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4728 if(SUCCEEDED(hr))
4730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4731 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4733 hr = IDirect3DDevice9_EndScene(device);
4734 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4736 color = getPixelColor(device, 578, 430);
4737 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4738 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4739 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4741 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4742 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4743 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4744 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4745 IDirect3DPixelShader9_Release(shader);
4746 IDirect3DPixelShader9_Release(shader2);
4747 IDirect3DTexture9_Release(texture);
4750 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4752 HRESULT hr;
4753 IDirect3D9 *d3d;
4754 IDirect3DTexture9 *texture = NULL;
4755 IDirect3DSurface9 *surface;
4756 DWORD color;
4757 const RECT r1 = {256, 256, 512, 512};
4758 const RECT r2 = {512, 256, 768, 512};
4759 const RECT r3 = {256, 512, 512, 768};
4760 const RECT r4 = {512, 512, 768, 768};
4761 unsigned int x, y;
4762 D3DLOCKED_RECT lr;
4763 memset(&lr, 0, sizeof(lr));
4765 IDirect3DDevice9_GetDirect3D(device, &d3d);
4766 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4767 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4768 skip("No autogenmipmap support\n");
4769 IDirect3D9_Release(d3d);
4770 return;
4772 IDirect3D9_Release(d3d);
4774 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4775 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4777 /* Make the mipmap big, so that a smaller mipmap is used
4779 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4780 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4781 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4783 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4784 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4785 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4786 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4787 for(y = 0; y < 1024; y++) {
4788 for(x = 0; x < 1024; x++) {
4789 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4790 POINT pt;
4792 pt.x = x;
4793 pt.y = y;
4794 if(PtInRect(&r1, pt)) {
4795 *dst = 0xffff0000;
4796 } else if(PtInRect(&r2, pt)) {
4797 *dst = 0xff00ff00;
4798 } else if(PtInRect(&r3, pt)) {
4799 *dst = 0xff0000ff;
4800 } else if(PtInRect(&r4, pt)) {
4801 *dst = 0xff000000;
4802 } else {
4803 *dst = 0xffffffff;
4807 hr = IDirect3DSurface9_UnlockRect(surface);
4808 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4809 IDirect3DSurface9_Release(surface);
4811 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4812 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4813 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4816 hr = IDirect3DDevice9_BeginScene(device);
4817 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4818 if(SUCCEEDED(hr)) {
4819 const float quad[] = {
4820 -0.5, -0.5, 0.1, 0.0, 0.0,
4821 -0.5, 0.5, 0.1, 0.0, 1.0,
4822 0.5, -0.5, 0.1, 1.0, 0.0,
4823 0.5, 0.5, 0.1, 1.0, 1.0
4826 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4827 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4829 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4830 hr = IDirect3DDevice9_EndScene(device);
4831 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4833 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4835 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4837 IDirect3DTexture9_Release(texture);
4839 color = getPixelColor(device, 200, 200);
4840 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4841 color = getPixelColor(device, 280, 200);
4842 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4843 color = getPixelColor(device, 360, 200);
4844 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4845 color = getPixelColor(device, 440, 200);
4846 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4847 color = getPixelColor(device, 200, 270);
4848 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4849 color = getPixelColor(device, 280, 270);
4850 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4851 color = getPixelColor(device, 360, 270);
4852 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4853 color = getPixelColor(device, 440, 270);
4854 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4855 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4859 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4861 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4862 IDirect3DVertexDeclaration9 *decl;
4863 HRESULT hr;
4864 DWORD color;
4865 DWORD shader_code_11[] = {
4866 0xfffe0101, /* vs_1_1 */
4867 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4868 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4869 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4870 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4871 0x0000ffff /* end */
4873 DWORD shader_code_11_2[] = {
4874 0xfffe0101, /* vs_1_1 */
4875 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4876 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4877 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4878 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4879 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4880 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4881 0x0000ffff /* end */
4883 DWORD shader_code_20[] = {
4884 0xfffe0200, /* vs_2_0 */
4885 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4886 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4887 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4888 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4889 0x0000ffff /* end */
4891 DWORD shader_code_20_2[] = {
4892 0xfffe0200, /* vs_2_0 */
4893 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4894 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4895 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4896 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4897 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4898 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4899 0x0000ffff /* end */
4901 static const D3DVERTEXELEMENT9 decl_elements[] = {
4902 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4903 D3DDECL_END()
4905 float quad1[] = {
4906 -1.0, -1.0, 0.1,
4907 0.0, -1.0, 0.1,
4908 -1.0, 0.0, 0.1,
4909 0.0, 0.0, 0.1
4911 float quad2[] = {
4912 0.0, -1.0, 0.1,
4913 1.0, -1.0, 0.1,
4914 0.0, 0.0, 0.1,
4915 1.0, 0.0, 0.1
4917 float quad3[] = {
4918 0.0, 0.0, 0.1,
4919 1.0, 0.0, 0.1,
4920 0.0, 1.0, 0.1,
4921 1.0, 1.0, 0.1
4923 float quad4[] = {
4924 -1.0, 0.0, 0.1,
4925 0.0, 0.0, 0.1,
4926 -1.0, 1.0, 0.1,
4927 0.0, 1.0, 0.1
4929 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4930 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4933 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4935 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4936 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4937 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4938 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4939 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4940 if(FAILED(hr)) shader_20 = NULL;
4941 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4942 if(FAILED(hr)) shader_20_2 = NULL;
4943 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4944 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4946 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4947 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4948 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4949 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4950 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4951 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4953 hr = IDirect3DDevice9_BeginScene(device);
4954 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4955 if(SUCCEEDED(hr))
4957 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4958 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4960 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4962 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4963 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4965 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4967 if(shader_20) {
4968 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4969 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4970 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4971 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4974 if(shader_20_2) {
4975 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4978 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4981 hr = IDirect3DDevice9_EndScene(device);
4982 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4985 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4987 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4990 color = getPixelColor(device, 160, 360);
4991 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4992 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4993 color = getPixelColor(device, 480, 360);
4994 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4995 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4996 if(shader_20) {
4997 color = getPixelColor(device, 480, 120);
4998 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4999 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5001 if(shader_20_2) {
5002 color = getPixelColor(device, 160, 120);
5003 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5004 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5007 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5009 IDirect3DVertexDeclaration9_Release(decl);
5010 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5011 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5012 IDirect3DVertexShader9_Release(shader_11_2);
5013 IDirect3DVertexShader9_Release(shader_11);
5016 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5018 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5019 HRESULT hr;
5020 DWORD color;
5021 DWORD shader_code_11[] = {
5022 0xffff0101, /* ps_1_1 */
5023 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5024 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5025 0x0000ffff /* end */
5027 DWORD shader_code_12[] = {
5028 0xffff0102, /* ps_1_2 */
5029 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5030 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5031 0x0000ffff /* end */
5033 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5034 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5035 * During development of this test, 1.3 shaders were verified too
5037 DWORD shader_code_14[] = {
5038 0xffff0104, /* ps_1_4 */
5039 /* Try to make one constant local. It gets clamped too, although the binary contains
5040 * the bigger numbers
5042 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5043 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5044 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5045 0x0000ffff /* end */
5047 DWORD shader_code_20[] = {
5048 0xffff0200, /* ps_2_0 */
5049 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5050 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5051 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5052 0x0000ffff /* end */
5054 float quad1[] = {
5055 -1.0, -1.0, 0.1,
5056 0.0, -1.0, 0.1,
5057 -1.0, 0.0, 0.1,
5058 0.0, 0.0, 0.1
5060 float quad2[] = {
5061 0.0, -1.0, 0.1,
5062 1.0, -1.0, 0.1,
5063 0.0, 0.0, 0.1,
5064 1.0, 0.0, 0.1
5066 float quad3[] = {
5067 0.0, 0.0, 0.1,
5068 1.0, 0.0, 0.1,
5069 0.0, 1.0, 0.1,
5070 1.0, 1.0, 0.1
5072 float quad4[] = {
5073 -1.0, 0.0, 0.1,
5074 0.0, 0.0, 0.1,
5075 -1.0, 1.0, 0.1,
5076 0.0, 1.0, 0.1
5078 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5079 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5081 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5082 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5084 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5085 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5086 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5087 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5088 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5089 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5090 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5091 if(FAILED(hr)) shader_20 = NULL;
5093 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5094 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5095 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5097 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5098 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5100 hr = IDirect3DDevice9_BeginScene(device);
5101 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5102 if(SUCCEEDED(hr))
5104 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5105 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5107 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5109 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5110 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5112 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5114 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5115 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5116 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5117 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5119 if(shader_20) {
5120 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5121 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5123 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5126 hr = IDirect3DDevice9_EndScene(device);
5127 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5130 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5132 color = getPixelColor(device, 160, 360);
5133 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5134 "quad 1 has color %08x, expected 0x00808000\n", color);
5135 color = getPixelColor(device, 480, 360);
5136 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5137 "quad 2 has color %08x, expected 0x00808000\n", color);
5138 color = getPixelColor(device, 480, 120);
5139 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5140 "quad 3 has color %08x, expected 0x00808000\n", color);
5141 if(shader_20) {
5142 color = getPixelColor(device, 160, 120);
5143 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5144 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5146 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5147 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5149 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5150 IDirect3DPixelShader9_Release(shader_14);
5151 IDirect3DPixelShader9_Release(shader_12);
5152 IDirect3DPixelShader9_Release(shader_11);
5155 static void dp2add_ps_test(IDirect3DDevice9 *device)
5157 IDirect3DPixelShader9 *shader_dp2add = NULL;
5158 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5159 HRESULT hr;
5160 DWORD color;
5162 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5163 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5164 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5165 * r0 first.
5166 * The result here for the r,g,b components should be roughly 0.5:
5167 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5168 static const DWORD shader_code_dp2add[] = {
5169 0xffff0200, /* ps_2_0 */
5170 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5172 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5173 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5175 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5176 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5177 0x0000ffff /* end */
5180 /* Test the _sat modifier, too. Result here should be:
5181 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5182 * _SAT: ==> 1.0
5183 * ADD: (1.0 + -0.5) = 0.5
5185 static const DWORD shader_code_dp2add_sat[] = {
5186 0xffff0200, /* ps_2_0 */
5187 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5189 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5190 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5191 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5193 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5194 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5195 0x0000ffff /* end */
5198 const float quad[] = {
5199 -1.0, -1.0, 0.1,
5200 1.0, -1.0, 0.1,
5201 -1.0, 1.0, 0.1,
5202 1.0, 1.0, 0.1
5206 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5207 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5209 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5210 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5212 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5213 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5215 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5216 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5218 if (shader_dp2add) {
5220 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5221 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5223 hr = IDirect3DDevice9_BeginScene(device);
5224 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5225 if(SUCCEEDED(hr))
5227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5228 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5230 hr = IDirect3DDevice9_EndScene(device);
5231 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5234 color = getPixelColor(device, 360, 240);
5235 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5236 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5241 IDirect3DPixelShader9_Release(shader_dp2add);
5242 } else {
5243 skip("dp2add shader creation failed\n");
5246 if (shader_dp2add_sat) {
5248 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5249 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5251 hr = IDirect3DDevice9_BeginScene(device);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5253 if(SUCCEEDED(hr))
5255 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5256 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5258 hr = IDirect3DDevice9_EndScene(device);
5259 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5262 color = getPixelColor(device, 360, 240);
5263 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5264 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5266 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5267 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5269 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5270 } else {
5271 skip("dp2add shader creation failed\n");
5274 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5275 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5278 static void cnd_test(IDirect3DDevice9 *device)
5280 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5281 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5282 HRESULT hr;
5283 DWORD color;
5284 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5285 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5286 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5288 DWORD shader_code_11[] = {
5289 0xffff0101, /* ps_1_1 */
5290 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5291 0x00000040, 0xb00f0000, /* texcoord t0 */
5292 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5293 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5294 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5295 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5296 0x0000ffff /* end */
5298 DWORD shader_code_12[] = {
5299 0xffff0102, /* ps_1_2 */
5300 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5301 0x00000040, 0xb00f0000, /* texcoord t0 */
5302 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5303 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5304 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5305 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5306 0x0000ffff /* end */
5308 DWORD shader_code_13[] = {
5309 0xffff0103, /* ps_1_3 */
5310 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5311 0x00000040, 0xb00f0000, /* texcoord t0 */
5312 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5313 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5314 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5315 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5316 0x0000ffff /* end */
5318 DWORD shader_code_14[] = {
5319 0xffff0104, /* ps_1_3 */
5320 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5321 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5322 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5323 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5324 0x0000ffff /* end */
5327 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5328 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5329 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5330 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5331 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5332 * well enough.
5334 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5335 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5336 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5337 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5339 DWORD shader_code_11_coissue[] = {
5340 0xffff0101, /* ps_1_1 */
5341 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5342 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5343 0x00000040, 0xb00f0000, /* texcoord t0 */
5344 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5345 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5346 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5347 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5348 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5349 /* 0x40000000 = D3DSI_COISSUE */
5350 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5351 0x0000ffff /* end */
5353 DWORD shader_code_12_coissue[] = {
5354 0xffff0102, /* ps_1_2 */
5355 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5356 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5357 0x00000040, 0xb00f0000, /* texcoord t0 */
5358 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5359 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5360 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5361 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5362 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5363 /* 0x40000000 = D3DSI_COISSUE */
5364 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5365 0x0000ffff /* end */
5367 DWORD shader_code_13_coissue[] = {
5368 0xffff0103, /* ps_1_3 */
5369 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5370 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5371 0x00000040, 0xb00f0000, /* texcoord t0 */
5372 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5373 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5374 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5375 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5376 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5377 /* 0x40000000 = D3DSI_COISSUE */
5378 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5379 0x0000ffff /* end */
5381 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5382 * compare against 0.5
5384 DWORD shader_code_14_coissue[] = {
5385 0xffff0104, /* ps_1_4 */
5386 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5387 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5388 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5389 /* 0x40000000 = D3DSI_COISSUE */
5390 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5391 0x0000ffff /* end */
5393 float quad1[] = {
5394 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5395 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5396 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5397 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5399 float quad2[] = {
5400 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5401 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5402 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5403 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5405 float quad3[] = {
5406 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5407 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5408 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5409 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5411 float quad4[] = {
5412 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5413 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5414 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5415 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5417 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5418 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5419 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5420 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5422 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5423 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5425 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5426 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5427 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5428 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5429 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5430 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5431 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5432 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5433 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5434 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5435 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5436 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5437 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5438 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5439 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5440 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5442 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5443 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5444 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5445 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5446 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5447 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5449 hr = IDirect3DDevice9_BeginScene(device);
5450 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5451 if(SUCCEEDED(hr))
5453 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5454 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5456 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5458 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5459 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5461 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5463 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5464 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5466 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5468 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5469 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5471 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5473 hr = IDirect3DDevice9_EndScene(device);
5474 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5477 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5478 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5480 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5481 color = getPixelColor(device, 158, 118);
5482 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5483 color = getPixelColor(device, 162, 118);
5484 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5485 color = getPixelColor(device, 158, 122);
5486 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5487 color = getPixelColor(device, 162, 122);
5488 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5490 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5491 color = getPixelColor(device, 158, 358);
5492 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5493 color = getPixelColor(device, 162, 358);
5494 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5495 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5496 color = getPixelColor(device, 158, 362);
5497 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5498 color = getPixelColor(device, 162, 362);
5499 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5500 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5502 /* 1.2 shader */
5503 color = getPixelColor(device, 478, 358);
5504 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5505 color = getPixelColor(device, 482, 358);
5506 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5507 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5508 color = getPixelColor(device, 478, 362);
5509 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5510 color = getPixelColor(device, 482, 362);
5511 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5512 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5514 /* 1.3 shader */
5515 color = getPixelColor(device, 478, 118);
5516 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5517 color = getPixelColor(device, 482, 118);
5518 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5519 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5520 color = getPixelColor(device, 478, 122);
5521 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5522 color = getPixelColor(device, 482, 122);
5523 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5524 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5526 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5529 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5530 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5531 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5532 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5533 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5534 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5536 hr = IDirect3DDevice9_BeginScene(device);
5537 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5538 if(SUCCEEDED(hr))
5540 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5541 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5543 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5545 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5548 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5550 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5551 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5553 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5555 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5556 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5558 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5560 hr = IDirect3DDevice9_EndScene(device);
5561 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5564 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5565 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5567 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5568 * that we swapped the values in c1 and c2 to make the other tests return some color
5570 color = getPixelColor(device, 158, 118);
5571 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5572 color = getPixelColor(device, 162, 118);
5573 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5574 color = getPixelColor(device, 158, 122);
5575 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5576 color = getPixelColor(device, 162, 122);
5577 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5579 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5580 * (The Win7 nvidia driver always selects c2)
5582 color = getPixelColor(device, 158, 358);
5583 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5584 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5585 color = getPixelColor(device, 162, 358);
5586 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5587 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5588 color = getPixelColor(device, 158, 362);
5589 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5590 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5591 color = getPixelColor(device, 162, 362);
5592 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5593 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5595 /* 1.2 shader */
5596 color = getPixelColor(device, 478, 358);
5597 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5598 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5599 color = getPixelColor(device, 482, 358);
5600 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5601 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5602 color = getPixelColor(device, 478, 362);
5603 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5604 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5605 color = getPixelColor(device, 482, 362);
5606 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5607 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5609 /* 1.3 shader */
5610 color = getPixelColor(device, 478, 118);
5611 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5612 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5613 color = getPixelColor(device, 482, 118);
5614 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5615 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5616 color = getPixelColor(device, 478, 122);
5617 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5618 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5619 color = getPixelColor(device, 482, 122);
5620 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5621 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5626 IDirect3DPixelShader9_Release(shader_14_coissue);
5627 IDirect3DPixelShader9_Release(shader_13_coissue);
5628 IDirect3DPixelShader9_Release(shader_12_coissue);
5629 IDirect3DPixelShader9_Release(shader_11_coissue);
5630 IDirect3DPixelShader9_Release(shader_14);
5631 IDirect3DPixelShader9_Release(shader_13);
5632 IDirect3DPixelShader9_Release(shader_12);
5633 IDirect3DPixelShader9_Release(shader_11);
5636 static void nested_loop_test(IDirect3DDevice9 *device) {
5637 const DWORD shader_code[] = {
5638 0xffff0300, /* ps_3_0 */
5639 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5640 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5641 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5642 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5643 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5644 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5645 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5646 0x0000001d, /* endloop */
5647 0x0000001d, /* endloop */
5648 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5649 0x0000ffff /* end */
5651 const DWORD vshader_code[] = {
5652 0xfffe0300, /* vs_3_0 */
5653 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5654 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5655 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5656 0x0000ffff /* end */
5658 IDirect3DPixelShader9 *shader;
5659 IDirect3DVertexShader9 *vshader;
5660 HRESULT hr;
5661 DWORD color;
5662 const float quad[] = {
5663 -1.0, -1.0, 0.1,
5664 1.0, -1.0, 0.1,
5665 -1.0, 1.0, 0.1,
5666 1.0, 1.0, 0.1
5669 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5670 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5671 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5672 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5673 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5674 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5675 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5676 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5677 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5678 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5682 hr = IDirect3DDevice9_BeginScene(device);
5683 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5684 if(SUCCEEDED(hr))
5686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5687 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5688 hr = IDirect3DDevice9_EndScene(device);
5689 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5692 color = getPixelColor(device, 360, 240);
5693 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5694 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5696 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5697 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5699 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5700 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5701 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5702 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5703 IDirect3DPixelShader9_Release(shader);
5704 IDirect3DVertexShader9_Release(vshader);
5707 struct varying_test_struct
5709 const DWORD *shader_code;
5710 IDirect3DPixelShader9 *shader;
5711 DWORD color, color_rhw;
5712 const char *name;
5713 BOOL todo, todo_rhw;
5716 struct hugeVertex
5718 float pos_x, pos_y, pos_z, rhw;
5719 float weight_1, weight_2, weight_3, weight_4;
5720 float index_1, index_2, index_3, index_4;
5721 float normal_1, normal_2, normal_3, normal_4;
5722 float fog_1, fog_2, fog_3, fog_4;
5723 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5724 float tangent_1, tangent_2, tangent_3, tangent_4;
5725 float binormal_1, binormal_2, binormal_3, binormal_4;
5726 float depth_1, depth_2, depth_3, depth_4;
5727 DWORD diffuse, specular;
5730 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5731 /* dcl_position: fails to compile */
5732 const DWORD blendweight_code[] = {
5733 0xffff0300, /* ps_3_0 */
5734 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5735 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5736 0x0000ffff /* end */
5738 const DWORD blendindices_code[] = {
5739 0xffff0300, /* ps_3_0 */
5740 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5741 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5742 0x0000ffff /* end */
5744 const DWORD normal_code[] = {
5745 0xffff0300, /* ps_3_0 */
5746 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5747 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5748 0x0000ffff /* end */
5750 /* psize: fails? */
5751 const DWORD texcoord0_code[] = {
5752 0xffff0300, /* ps_3_0 */
5753 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5754 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5755 0x0000ffff /* end */
5757 const DWORD tangent_code[] = {
5758 0xffff0300, /* ps_3_0 */
5759 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5760 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5761 0x0000ffff /* end */
5763 const DWORD binormal_code[] = {
5764 0xffff0300, /* ps_3_0 */
5765 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5766 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5767 0x0000ffff /* end */
5769 /* tessfactor: fails */
5770 /* positiont: fails */
5771 const DWORD color_code[] = {
5772 0xffff0300, /* ps_3_0 */
5773 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5774 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5775 0x0000ffff /* end */
5777 const DWORD fog_code[] = {
5778 0xffff0300, /* ps_3_0 */
5779 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5780 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5781 0x0000ffff /* end */
5783 const DWORD depth_code[] = {
5784 0xffff0300, /* ps_3_0 */
5785 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5786 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5787 0x0000ffff /* end */
5789 const DWORD specular_code[] = {
5790 0xffff0300, /* ps_3_0 */
5791 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5792 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5793 0x0000ffff /* end */
5795 /* sample: fails */
5797 struct varying_test_struct tests[] = {
5798 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5799 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5800 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5801 /* Why does dx not forward the texcoord? */
5802 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5803 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5804 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5805 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5806 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5807 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5808 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5810 /* Declare a monster vertex type :-) */
5811 static const D3DVERTEXELEMENT9 decl_elements[] = {
5812 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5813 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5814 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5815 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5816 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5817 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5818 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5819 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5820 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5821 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5822 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5823 D3DDECL_END()
5825 struct hugeVertex data[4] = {
5827 -1.0, -1.0, 0.1, 1.0,
5828 0.1, 0.1, 0.1, 0.1,
5829 0.2, 0.2, 0.2, 0.2,
5830 0.3, 0.3, 0.3, 0.3,
5831 0.4, 0.4, 0.4, 0.4,
5832 0.50, 0.55, 0.55, 0.55,
5833 0.6, 0.6, 0.6, 0.7,
5834 0.7, 0.7, 0.7, 0.6,
5835 0.8, 0.8, 0.8, 0.8,
5836 0xe6e6e6e6, /* 0.9 * 256 */
5837 0x224488ff /* Nothing special */
5840 1.0, -1.0, 0.1, 1.0,
5841 0.1, 0.1, 0.1, 0.1,
5842 0.2, 0.2, 0.2, 0.2,
5843 0.3, 0.3, 0.3, 0.3,
5844 0.4, 0.4, 0.4, 0.4,
5845 0.50, 0.55, 0.55, 0.55,
5846 0.6, 0.6, 0.6, 0.7,
5847 0.7, 0.7, 0.7, 0.6,
5848 0.8, 0.8, 0.8, 0.8,
5849 0xe6e6e6e6, /* 0.9 * 256 */
5850 0x224488ff /* Nothing special */
5853 -1.0, 1.0, 0.1, 1.0,
5854 0.1, 0.1, 0.1, 0.1,
5855 0.2, 0.2, 0.2, 0.2,
5856 0.3, 0.3, 0.3, 0.3,
5857 0.4, 0.4, 0.4, 0.4,
5858 0.50, 0.55, 0.55, 0.55,
5859 0.6, 0.6, 0.6, 0.7,
5860 0.7, 0.7, 0.7, 0.6,
5861 0.8, 0.8, 0.8, 0.8,
5862 0xe6e6e6e6, /* 0.9 * 256 */
5863 0x224488ff /* Nothing special */
5866 1.0, 1.0, 0.1, 1.0,
5867 0.1, 0.1, 0.1, 0.1,
5868 0.2, 0.2, 0.2, 0.2,
5869 0.3, 0.3, 0.3, 0.3,
5870 0.4, 0.4, 0.4, 0.4,
5871 0.50, 0.55, 0.55, 0.55,
5872 0.6, 0.6, 0.6, 0.7,
5873 0.7, 0.7, 0.7, 0.6,
5874 0.8, 0.8, 0.8, 0.8,
5875 0xe6e6e6e6, /* 0.9 * 256 */
5876 0x224488ff /* Nothing special */
5879 struct hugeVertex data2[4];
5880 IDirect3DVertexDeclaration9 *decl;
5881 HRESULT hr;
5882 unsigned int i;
5883 DWORD color, r, g, b, r_e, g_e, b_e;
5885 memcpy(data2, data, sizeof(data2));
5886 data2[0].pos_x = 0; data2[0].pos_y = 0;
5887 data2[1].pos_x = 640; data2[1].pos_y = 0;
5888 data2[2].pos_x = 0; data2[2].pos_y = 480;
5889 data2[3].pos_x = 640; data2[3].pos_y = 480;
5891 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5893 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5894 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5896 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5898 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5899 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5900 tests[i].name, hr);
5903 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5904 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5905 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5907 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5908 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5910 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5911 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5913 hr = IDirect3DDevice9_BeginScene(device);
5914 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5915 if(SUCCEEDED(hr))
5917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5918 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5919 hr = IDirect3DDevice9_EndScene(device);
5920 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5923 color = getPixelColor(device, 360, 240);
5924 r = color & 0x00ff0000 >> 16;
5925 g = color & 0x0000ff00 >> 8;
5926 b = color & 0x000000ff;
5927 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5928 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5929 b_e = tests[i].color_rhw & 0x000000ff;
5931 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5932 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5934 if(tests[i].todo_rhw) {
5935 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5936 * pipeline
5938 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5939 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5940 tests[i].name, color, tests[i].color_rhw);
5941 } else {
5942 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5943 "Test %s returned color 0x%08x, expected 0x%08x\n",
5944 tests[i].name, color, tests[i].color_rhw);
5948 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5950 IDirect3DPixelShader9_Release(tests[i].shader);
5953 IDirect3DVertexDeclaration9_Release(decl);
5956 static void test_compare_instructions(IDirect3DDevice9 *device)
5958 DWORD shader_sge_vec_code[] = {
5959 0xfffe0101, /* vs_1_1 */
5960 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5961 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5962 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5963 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5964 0x0000ffff /* end */
5966 DWORD shader_slt_vec_code[] = {
5967 0xfffe0101, /* vs_1_1 */
5968 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5969 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5970 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5971 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5972 0x0000ffff /* end */
5974 DWORD shader_sge_scalar_code[] = {
5975 0xfffe0101, /* vs_1_1 */
5976 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5977 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5978 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5979 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5980 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5981 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5982 0x0000ffff /* end */
5984 DWORD shader_slt_scalar_code[] = {
5985 0xfffe0101, /* vs_1_1 */
5986 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5987 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5988 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5989 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5990 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5991 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5992 0x0000ffff /* end */
5994 IDirect3DVertexShader9 *shader_sge_vec;
5995 IDirect3DVertexShader9 *shader_slt_vec;
5996 IDirect3DVertexShader9 *shader_sge_scalar;
5997 IDirect3DVertexShader9 *shader_slt_scalar;
5998 HRESULT hr, color;
5999 float quad1[] = {
6000 -1.0, -1.0, 0.1,
6001 0.0, -1.0, 0.1,
6002 -1.0, 0.0, 0.1,
6003 0.0, 0.0, 0.1
6005 float quad2[] = {
6006 0.0, -1.0, 0.1,
6007 1.0, -1.0, 0.1,
6008 0.0, 0.0, 0.1,
6009 1.0, 0.0, 0.1
6011 float quad3[] = {
6012 -1.0, 0.0, 0.1,
6013 0.0, 0.0, 0.1,
6014 -1.0, 1.0, 0.1,
6015 0.0, 1.0, 0.1
6017 float quad4[] = {
6018 0.0, 0.0, 0.1,
6019 1.0, 0.0, 0.1,
6020 0.0, 1.0, 0.1,
6021 1.0, 1.0, 0.1
6023 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6024 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6026 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6027 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6029 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6031 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6033 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6034 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6035 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6036 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6037 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6038 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6039 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6040 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6041 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6042 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6044 hr = IDirect3DDevice9_BeginScene(device);
6045 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6046 if(SUCCEEDED(hr))
6048 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6051 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6053 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6054 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6056 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6058 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6059 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6061 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6063 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6064 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6066 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6067 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6069 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6071 hr = IDirect3DDevice9_EndScene(device);
6072 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6075 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6076 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6078 color = getPixelColor(device, 160, 360);
6079 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6080 color = getPixelColor(device, 480, 360);
6081 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6082 color = getPixelColor(device, 160, 120);
6083 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6084 color = getPixelColor(device, 480, 160);
6085 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6087 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6088 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6090 IDirect3DVertexShader9_Release(shader_sge_vec);
6091 IDirect3DVertexShader9_Release(shader_slt_vec);
6092 IDirect3DVertexShader9_Release(shader_sge_scalar);
6093 IDirect3DVertexShader9_Release(shader_slt_scalar);
6096 static void test_vshader_input(IDirect3DDevice9 *device)
6098 static const DWORD swapped_shader_code_3[] =
6100 0xfffe0300, /* vs_3_0 */
6101 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6102 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6103 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6104 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6105 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6106 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6107 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6108 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6109 0x0000ffff /* end */
6111 static const DWORD swapped_shader_code_1[] =
6113 0xfffe0101, /* vs_1_1 */
6114 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6115 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6116 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6117 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6118 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6119 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6120 0x0000ffff /* end */
6122 static const DWORD swapped_shader_code_2[] =
6124 0xfffe0200, /* vs_2_0 */
6125 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6126 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6127 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6128 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6129 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6130 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6131 0x0000ffff /* end */
6133 static const DWORD texcoord_color_shader_code_3[] =
6135 0xfffe0300, /* vs_3_0 */
6136 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6137 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6138 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6139 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6140 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6141 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6142 0x0000ffff /* end */
6144 static const DWORD texcoord_color_shader_code_2[] =
6146 0xfffe0200, /* vs_2_0 */
6147 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6148 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6149 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6150 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6151 0x0000ffff /* end */
6153 static const DWORD texcoord_color_shader_code_1[] =
6155 0xfffe0101, /* vs_1_1 */
6156 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6157 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6158 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6159 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6160 0x0000ffff /* end */
6162 static const DWORD color_color_shader_code_3[] =
6164 0xfffe0300, /* vs_3_0 */
6165 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6166 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6167 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6168 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6169 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6170 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6171 0x0000ffff /* end */
6173 static const DWORD color_color_shader_code_2[] =
6175 0xfffe0200, /* vs_2_0 */
6176 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6177 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6178 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6179 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6180 0x0000ffff /* end */
6182 static const DWORD color_color_shader_code_1[] =
6184 0xfffe0101, /* vs_1_1 */
6185 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6186 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6187 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6188 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6189 0x0000ffff /* end */
6191 static const DWORD ps3_code[] =
6193 0xffff0300, /* ps_3_0 */
6194 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6195 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6196 0x0000ffff /* end */
6198 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6199 IDirect3DPixelShader9 *ps;
6200 HRESULT hr;
6201 DWORD color;
6202 float quad1[] = {
6203 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6204 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6205 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6206 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6208 float quad2[] = {
6209 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6210 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6211 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6212 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6214 float quad3[] = {
6215 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6216 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6217 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6218 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6220 float quad4[] = {
6221 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6222 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6223 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6224 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6226 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6227 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6228 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6229 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6230 D3DDECL_END()
6232 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6233 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6234 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6235 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6236 D3DDECL_END()
6238 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6239 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6240 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6241 D3DDECL_END()
6243 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6244 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6245 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6246 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6247 D3DDECL_END()
6249 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6250 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6251 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6252 D3DDECL_END()
6254 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6255 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6256 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6257 D3DDECL_END()
6259 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6260 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6261 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6262 D3DDECL_END()
6264 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6265 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6266 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6267 D3DDECL_END()
6269 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6270 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6271 unsigned int i;
6272 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6273 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6275 struct vertex quad1_color[] = {
6276 {-1.0, -1.0, 0.1, 0x00ff8040},
6277 { 0.0, -1.0, 0.1, 0x00ff8040},
6278 {-1.0, 0.0, 0.1, 0x00ff8040},
6279 { 0.0, 0.0, 0.1, 0x00ff8040}
6281 struct vertex quad2_color[] = {
6282 { 0.0, -1.0, 0.1, 0x00ff8040},
6283 { 1.0, -1.0, 0.1, 0x00ff8040},
6284 { 0.0, 0.0, 0.1, 0x00ff8040},
6285 { 1.0, 0.0, 0.1, 0x00ff8040}
6287 struct vertex quad3_color[] = {
6288 {-1.0, 0.0, 0.1, 0x00ff8040},
6289 { 0.0, 0.0, 0.1, 0x00ff8040},
6290 {-1.0, 1.0, 0.1, 0x00ff8040},
6291 { 0.0, 1.0, 0.1, 0x00ff8040}
6293 float quad4_color[] = {
6294 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6295 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6296 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6297 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6300 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6301 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6302 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6304 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6305 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6306 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6307 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6309 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6310 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6311 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6312 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6313 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6314 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6315 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6316 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6318 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6319 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6321 for(i = 1; i <= 3; i++) {
6322 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6323 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6324 if(i == 3) {
6325 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6326 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6327 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6328 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6329 } else if(i == 2){
6330 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6331 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6332 } else if(i == 1) {
6333 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6334 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6337 hr = IDirect3DDevice9_BeginScene(device);
6338 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6339 if(SUCCEEDED(hr))
6341 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6342 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6344 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6345 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6346 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6347 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6349 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6350 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6352 if(i == 3 || i == 2) {
6353 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6354 } else if(i == 1) {
6355 /* Succeeds or fails, depending on SW or HW vertex processing */
6356 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6359 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6360 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6362 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6364 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6365 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6366 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6367 if(i == 3 || i == 2) {
6368 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6369 } else if(i == 1) {
6370 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6373 hr = IDirect3DDevice9_EndScene(device);
6374 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6377 if(i == 3 || i == 2) {
6378 color = getPixelColor(device, 160, 360);
6379 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6380 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6382 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6383 color = getPixelColor(device, 480, 360);
6384 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6385 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6386 color = getPixelColor(device, 160, 120);
6387 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6388 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6389 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6391 color = getPixelColor(device, 480, 160);
6392 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6393 } else if(i == 1) {
6394 color = getPixelColor(device, 160, 360);
6395 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6396 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6397 color = getPixelColor(device, 480, 360);
6398 /* Accept the clear color as well in this case, since SW VP returns an error */
6399 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6400 color = getPixelColor(device, 160, 120);
6401 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6402 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6403 color = getPixelColor(device, 480, 160);
6404 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6408 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6413 /* Now find out if the whole streams are re-read, or just the last active value for the
6414 * vertices is used.
6416 hr = IDirect3DDevice9_BeginScene(device);
6417 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6418 if(SUCCEEDED(hr))
6420 float quad1_modified[] = {
6421 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6422 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6423 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6424 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6426 float quad2_modified[] = {
6427 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6428 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6429 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6430 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6433 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6434 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6436 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6437 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6439 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6441 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6442 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6444 if(i == 3 || i == 2) {
6445 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6446 } else if(i == 1) {
6447 /* Succeeds or fails, depending on SW or HW vertex processing */
6448 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6451 hr = IDirect3DDevice9_EndScene(device);
6452 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6455 color = getPixelColor(device, 480, 350);
6456 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6457 * as well.
6459 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6460 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6461 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6462 * refrast's result.
6464 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6466 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6467 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6469 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6470 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6472 IDirect3DDevice9_SetVertexShader(device, NULL);
6473 IDirect3DDevice9_SetPixelShader(device, NULL);
6474 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6476 IDirect3DVertexShader9_Release(swapped_shader);
6479 for(i = 1; i <= 3; i++) {
6480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6481 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6482 if(i == 3) {
6483 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6484 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6485 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6486 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6487 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6488 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6489 } else if(i == 2){
6490 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6491 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6492 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6493 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6494 } else if(i == 1) {
6495 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6496 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6497 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6498 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6501 hr = IDirect3DDevice9_BeginScene(device);
6502 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6503 if(SUCCEEDED(hr))
6505 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6506 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6507 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6508 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6510 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6512 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6513 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6515 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6516 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6517 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6518 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6520 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6522 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6523 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6524 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6525 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6526 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6527 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6529 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6530 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6532 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6534 hr = IDirect3DDevice9_EndScene(device);
6535 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6537 IDirect3DDevice9_SetVertexShader(device, NULL);
6538 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6539 IDirect3DDevice9_SetPixelShader(device, NULL);
6541 color = getPixelColor(device, 160, 360);
6542 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6543 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6544 color = getPixelColor(device, 480, 360);
6545 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6546 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6547 color = getPixelColor(device, 160, 120);
6548 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6549 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6550 color = getPixelColor(device, 480, 160);
6551 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6552 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6554 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6555 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6557 IDirect3DVertexShader9_Release(texcoord_color_shader);
6558 IDirect3DVertexShader9_Release(color_color_shader);
6561 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6562 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6563 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6564 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6566 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6567 IDirect3DVertexDeclaration9_Release(decl_color_color);
6568 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6569 IDirect3DVertexDeclaration9_Release(decl_color_float);
6571 IDirect3DPixelShader9_Release(ps);
6574 static void srgbtexture_test(IDirect3DDevice9 *device)
6576 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6577 * texture stage state to render a quad using that texture. The resulting
6578 * color components should be 0x36 (~ 0.21), per this formula:
6579 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6580 * This is true where srgb_color > 0.04045.
6582 IDirect3D9 *d3d = NULL;
6583 HRESULT hr;
6584 LPDIRECT3DTEXTURE9 texture = NULL;
6585 LPDIRECT3DSURFACE9 surface = NULL;
6586 D3DLOCKED_RECT lr;
6587 DWORD color;
6588 float quad[] = {
6589 -1.0, 1.0, 0.0, 0.0, 0.0,
6590 1.0, 1.0, 0.0, 1.0, 0.0,
6591 -1.0, -1.0, 0.0, 0.0, 1.0,
6592 1.0, -1.0, 0.0, 1.0, 1.0,
6596 memset(&lr, 0, sizeof(lr));
6597 IDirect3DDevice9_GetDirect3D(device, &d3d);
6598 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6599 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6600 D3DFMT_A8R8G8B8) != D3D_OK) {
6601 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6602 goto out;
6605 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6606 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6607 &texture, NULL);
6608 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6609 if(!texture) {
6610 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6611 goto out;
6613 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6614 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6616 fill_surface(surface, 0xff7f7f7f);
6617 IDirect3DSurface9_Release(surface);
6619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6621 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6622 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6624 hr = IDirect3DDevice9_BeginScene(device);
6625 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6626 if(SUCCEEDED(hr))
6628 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6629 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6632 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6635 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6636 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6638 hr = IDirect3DDevice9_EndScene(device);
6639 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6642 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6643 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6644 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6645 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6647 color = getPixelColor(device, 320, 240);
6648 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6650 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6651 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6653 out:
6654 if(texture) IDirect3DTexture9_Release(texture);
6655 IDirect3D9_Release(d3d);
6658 static void shademode_test(IDirect3DDevice9 *device)
6660 /* Render a quad and try all of the different fixed function shading models. */
6661 HRESULT hr;
6662 DWORD color0, color1;
6663 DWORD color0_gouraud = 0, color1_gouraud = 0;
6664 DWORD shademode = D3DSHADE_FLAT;
6665 DWORD primtype = D3DPT_TRIANGLESTRIP;
6666 LPVOID data = NULL;
6667 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6668 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6669 UINT i, j;
6670 struct vertex quad_strip[] =
6672 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6673 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6674 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6675 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6677 struct vertex quad_list[] =
6679 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6680 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6681 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6683 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6684 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6685 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6688 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6689 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6690 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6691 if (FAILED(hr)) goto bail;
6693 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6694 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6695 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6696 if (FAILED(hr)) goto bail;
6698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6704 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6705 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6706 memcpy(data, quad_strip, sizeof(quad_strip));
6707 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6708 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6710 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6711 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6712 memcpy(data, quad_list, sizeof(quad_list));
6713 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6714 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6716 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6717 * the color fixups we have to do for FLAT shading will be dependent on that. */
6718 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6719 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6721 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6722 for (j=0; j<2; j++) {
6724 /* Inner loop just changes the D3DRS_SHADEMODE */
6725 for (i=0; i<3; i++) {
6726 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6727 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6732 hr = IDirect3DDevice9_BeginScene(device);
6733 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6734 if(SUCCEEDED(hr))
6736 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6737 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6739 hr = IDirect3DDevice9_EndScene(device);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6743 /* Sample two spots from the output */
6744 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6745 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6746 switch(shademode) {
6747 case D3DSHADE_FLAT:
6748 /* Should take the color of the first vertex of each triangle */
6749 if (0)
6751 /* This test depends on EXT_provoking_vertex being
6752 * available. This extension is currently (20090810)
6753 * not common enough to let the test fail if it isn't
6754 * present. */
6755 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6756 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6758 shademode = D3DSHADE_GOURAUD;
6759 break;
6760 case D3DSHADE_GOURAUD:
6761 /* Should be an interpolated blend */
6763 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6764 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6765 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6766 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6768 color0_gouraud = color0;
6769 color1_gouraud = color1;
6771 shademode = D3DSHADE_PHONG;
6772 break;
6773 case D3DSHADE_PHONG:
6774 /* Should be the same as GOURAUD, since no hardware implements this */
6775 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6776 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6777 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6778 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6780 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6781 color0_gouraud, color0);
6782 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6783 color1_gouraud, color1);
6784 break;
6788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6791 /* Now, do it all over again with a TRIANGLELIST */
6792 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6793 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6794 primtype = D3DPT_TRIANGLELIST;
6795 shademode = D3DSHADE_FLAT;
6798 bail:
6799 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6800 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6802 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6804 if (vb_strip)
6805 IDirect3DVertexBuffer9_Release(vb_strip);
6806 if (vb_list)
6807 IDirect3DVertexBuffer9_Release(vb_list);
6810 static void alpha_test(IDirect3DDevice9 *device)
6812 HRESULT hr;
6813 IDirect3DTexture9 *offscreenTexture;
6814 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6815 DWORD color;
6817 struct vertex quad1[] =
6819 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6820 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6821 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6822 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6824 struct vertex quad2[] =
6826 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6827 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6828 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6829 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6831 static const float composite_quad[][5] = {
6832 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6833 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6834 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6835 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6838 /* Clear the render target with alpha = 0.5 */
6839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6840 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6842 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6843 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6845 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6846 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6847 if(!backbuffer) {
6848 goto out;
6851 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6852 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6853 if(!offscreen) {
6854 goto out;
6857 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6858 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6860 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6861 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6862 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6863 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6864 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6865 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6866 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6867 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6869 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6872 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6873 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6875 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6877 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6881 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6887 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6888 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6890 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6891 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6892 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6893 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6894 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6895 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6896 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6899 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6901 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6903 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6906 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6908 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6910 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6912 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6913 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6915 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6916 * Disable alpha blending for the final composition
6918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6919 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6921 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6923 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6926 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6927 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6928 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6930 hr = IDirect3DDevice9_EndScene(device);
6931 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6934 color = getPixelColor(device, 160, 360);
6935 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6936 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6938 color = getPixelColor(device, 160, 120);
6939 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6940 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6942 color = getPixelColor(device, 480, 360);
6943 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6944 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6946 color = getPixelColor(device, 480, 120);
6947 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6948 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6950 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6952 out:
6953 /* restore things */
6954 if(backbuffer) {
6955 IDirect3DSurface9_Release(backbuffer);
6957 if(offscreenTexture) {
6958 IDirect3DTexture9_Release(offscreenTexture);
6960 if(offscreen) {
6961 IDirect3DSurface9_Release(offscreen);
6965 struct vertex_shortcolor {
6966 float x, y, z;
6967 unsigned short r, g, b, a;
6969 struct vertex_floatcolor {
6970 float x, y, z;
6971 float r, g, b, a;
6974 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6976 HRESULT hr;
6977 BOOL s_ok, ub_ok, f_ok;
6978 DWORD color, size, i;
6979 void *data;
6980 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6982 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6983 D3DDECL_END()
6985 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6987 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6988 D3DDECL_END()
6990 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6991 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6992 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6993 D3DDECL_END()
6995 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6996 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6997 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6998 D3DDECL_END()
7000 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7001 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7002 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7003 D3DDECL_END()
7005 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7006 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7007 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7008 D3DDECL_END()
7010 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7011 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7012 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7013 D3DDECL_END()
7015 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7016 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7017 IDirect3DVertexBuffer9 *vb, *vb2;
7018 struct vertex quad1[] = /* D3DCOLOR */
7020 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7021 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7022 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7023 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7025 struct vertex quad2[] = /* UBYTE4N */
7027 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7028 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7029 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7030 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7032 struct vertex_shortcolor quad3[] = /* short */
7034 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7035 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7036 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7037 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7039 struct vertex_floatcolor quad4[] =
7041 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7042 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7043 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7044 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7046 DWORD colors[] = {
7047 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7048 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7049 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7050 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7051 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7052 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7053 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7054 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7055 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7056 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7057 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7058 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7059 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7060 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7061 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7062 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7064 float quads[] = {
7065 -1.0, -1.0, 0.1,
7066 -1.0, 0.0, 0.1,
7067 0.0, -1.0, 0.1,
7068 0.0, 0.0, 0.1,
7070 0.0, -1.0, 0.1,
7071 0.0, 0.0, 0.1,
7072 1.0, -1.0, 0.1,
7073 1.0, 0.0, 0.1,
7075 0.0, 0.0, 0.1,
7076 0.0, 1.0, 0.1,
7077 1.0, 0.0, 0.1,
7078 1.0, 1.0, 0.1,
7080 -1.0, 0.0, 0.1,
7081 -1.0, 1.0, 0.1,
7082 0.0, 0.0, 0.1,
7083 0.0, 1.0, 0.1
7085 struct tvertex quad_transformed[] = {
7086 { 90, 110, 0.1, 2.0, 0x00ffff00},
7087 { 570, 110, 0.1, 2.0, 0x00ffff00},
7088 { 90, 300, 0.1, 2.0, 0x00ffff00},
7089 { 570, 300, 0.1, 2.0, 0x00ffff00}
7091 D3DCAPS9 caps;
7093 memset(&caps, 0, sizeof(caps));
7094 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7095 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7098 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7100 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7101 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7102 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7103 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7104 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7105 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7106 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7107 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7108 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7109 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7110 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7111 } else {
7112 trace("D3DDTCAPS_UBYTE4N not supported\n");
7113 dcl_ubyte_2 = NULL;
7114 dcl_ubyte = NULL;
7116 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7117 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7118 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7119 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7121 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7122 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7123 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7124 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7126 hr = IDirect3DDevice9_BeginScene(device);
7127 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7128 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7129 if(SUCCEEDED(hr)) {
7130 if(dcl_color) {
7131 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7132 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7134 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7137 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7138 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7139 * using software vertex processing. Doh!
7141 if(dcl_ubyte) {
7142 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7143 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7145 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7146 ub_ok = SUCCEEDED(hr);
7149 if(dcl_short) {
7150 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7151 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7153 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7154 s_ok = SUCCEEDED(hr);
7157 if(dcl_float) {
7158 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7161 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7162 f_ok = SUCCEEDED(hr);
7165 hr = IDirect3DDevice9_EndScene(device);
7166 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7169 if(dcl_short) {
7170 color = getPixelColor(device, 480, 360);
7171 ok(color == 0x000000ff || !s_ok,
7172 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7174 if(dcl_ubyte) {
7175 color = getPixelColor(device, 160, 120);
7176 ok(color == 0x0000ffff || !ub_ok,
7177 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7179 if(dcl_color) {
7180 color = getPixelColor(device, 160, 360);
7181 ok(color == 0x00ffff00,
7182 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7184 if(dcl_float) {
7185 color = getPixelColor(device, 480, 120);
7186 ok(color == 0x00ff0000 || !f_ok,
7187 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7189 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7191 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7192 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7193 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7194 * whether the immediate mode code works
7196 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7197 hr = IDirect3DDevice9_BeginScene(device);
7198 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7199 if(SUCCEEDED(hr)) {
7200 if(dcl_color) {
7201 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7202 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7203 memcpy(data, quad1, sizeof(quad1));
7204 hr = IDirect3DVertexBuffer9_Unlock(vb);
7205 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7206 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7207 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7208 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7209 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7210 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7211 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7214 if(dcl_ubyte) {
7215 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7216 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7217 memcpy(data, quad2, sizeof(quad2));
7218 hr = IDirect3DVertexBuffer9_Unlock(vb);
7219 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7220 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7222 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7223 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7224 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7225 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7226 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7227 ub_ok = SUCCEEDED(hr);
7230 if(dcl_short) {
7231 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7232 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7233 memcpy(data, quad3, sizeof(quad3));
7234 hr = IDirect3DVertexBuffer9_Unlock(vb);
7235 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7236 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7238 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7239 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7240 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7241 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7242 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7243 s_ok = SUCCEEDED(hr);
7246 if(dcl_float) {
7247 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7248 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7249 memcpy(data, quad4, sizeof(quad4));
7250 hr = IDirect3DVertexBuffer9_Unlock(vb);
7251 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7252 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7253 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7254 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7255 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7256 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7257 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7258 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7259 f_ok = SUCCEEDED(hr);
7262 hr = IDirect3DDevice9_EndScene(device);
7263 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7266 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7267 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7268 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7269 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7271 if(dcl_short) {
7272 color = getPixelColor(device, 480, 360);
7273 ok(color == 0x000000ff || !s_ok,
7274 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7276 if(dcl_ubyte) {
7277 color = getPixelColor(device, 160, 120);
7278 ok(color == 0x0000ffff || !ub_ok,
7279 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7281 if(dcl_color) {
7282 color = getPixelColor(device, 160, 360);
7283 ok(color == 0x00ffff00,
7284 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7286 if(dcl_float) {
7287 color = getPixelColor(device, 480, 120);
7288 ok(color == 0x00ff0000 || !f_ok,
7289 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7291 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7294 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7296 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7297 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7298 memcpy(data, quad_transformed, sizeof(quad_transformed));
7299 hr = IDirect3DVertexBuffer9_Unlock(vb);
7300 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7302 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7303 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7305 hr = IDirect3DDevice9_BeginScene(device);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307 if(SUCCEEDED(hr)) {
7308 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7309 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7310 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7311 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7313 hr = IDirect3DDevice9_EndScene(device);
7314 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7317 color = getPixelColor(device, 88, 108);
7318 ok(color == 0x000000ff,
7319 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7320 color = getPixelColor(device, 92, 108);
7321 ok(color == 0x000000ff,
7322 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7323 color = getPixelColor(device, 88, 112);
7324 ok(color == 0x000000ff,
7325 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7326 color = getPixelColor(device, 92, 112);
7327 ok(color == 0x00ffff00,
7328 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7330 color = getPixelColor(device, 568, 108);
7331 ok(color == 0x000000ff,
7332 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7333 color = getPixelColor(device, 572, 108);
7334 ok(color == 0x000000ff,
7335 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7336 color = getPixelColor(device, 568, 112);
7337 ok(color == 0x00ffff00,
7338 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7339 color = getPixelColor(device, 572, 112);
7340 ok(color == 0x000000ff,
7341 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7343 color = getPixelColor(device, 88, 298);
7344 ok(color == 0x000000ff,
7345 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7346 color = getPixelColor(device, 92, 298);
7347 ok(color == 0x00ffff00,
7348 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7349 color = getPixelColor(device, 88, 302);
7350 ok(color == 0x000000ff,
7351 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7352 color = getPixelColor(device, 92, 302);
7353 ok(color == 0x000000ff,
7354 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7356 color = getPixelColor(device, 568, 298);
7357 ok(color == 0x00ffff00,
7358 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7359 color = getPixelColor(device, 572, 298);
7360 ok(color == 0x000000ff,
7361 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7362 color = getPixelColor(device, 568, 302);
7363 ok(color == 0x000000ff,
7364 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7365 color = getPixelColor(device, 572, 302);
7366 ok(color == 0x000000ff,
7367 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7369 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7371 /* This test is pointless without those two declarations: */
7372 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7373 skip("color-ubyte switching test declarations aren't supported\n");
7374 goto out;
7377 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7378 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7379 memcpy(data, quads, sizeof(quads));
7380 hr = IDirect3DVertexBuffer9_Unlock(vb);
7381 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7382 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7383 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7384 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7385 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7386 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7387 memcpy(data, colors, sizeof(colors));
7388 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7391 for(i = 0; i < 2; i++) {
7392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7395 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7396 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7397 if(i == 0) {
7398 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7399 } else {
7400 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7402 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7404 hr = IDirect3DDevice9_BeginScene(device);
7405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7406 ub_ok = FALSE;
7407 if(SUCCEEDED(hr)) {
7408 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7409 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7410 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7411 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7412 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7413 ub_ok = SUCCEEDED(hr);
7415 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7417 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7418 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7420 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7421 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7422 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7423 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7424 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7425 ub_ok = (SUCCEEDED(hr) && ub_ok);
7427 hr = IDirect3DDevice9_EndScene(device);
7428 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7431 if(i == 0) {
7432 color = getPixelColor(device, 480, 360);
7433 ok(color == 0x00ff0000,
7434 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7435 color = getPixelColor(device, 160, 120);
7436 ok(color == 0x00ffffff,
7437 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7438 color = getPixelColor(device, 160, 360);
7439 ok(color == 0x000000ff || !ub_ok,
7440 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7441 color = getPixelColor(device, 480, 120);
7442 ok(color == 0x000000ff || !ub_ok,
7443 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7444 } else {
7445 color = getPixelColor(device, 480, 360);
7446 ok(color == 0x000000ff,
7447 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7448 color = getPixelColor(device, 160, 120);
7449 ok(color == 0x00ffffff,
7450 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7451 color = getPixelColor(device, 160, 360);
7452 ok(color == 0x00ff0000 || !ub_ok,
7453 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7454 color = getPixelColor(device, 480, 120);
7455 ok(color == 0x00ff0000 || !ub_ok,
7456 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7458 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7461 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7462 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7463 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7465 IDirect3DVertexBuffer9_Release(vb2);
7467 out:
7468 IDirect3DVertexBuffer9_Release(vb);
7469 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7470 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7471 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7472 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7473 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7474 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7475 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7478 struct vertex_float16color {
7479 float x, y, z;
7480 DWORD c1, c2;
7483 static void test_vshader_float16(IDirect3DDevice9 *device)
7485 HRESULT hr;
7486 DWORD color;
7487 void *data;
7488 static const D3DVERTEXELEMENT9 decl_elements[] = {
7489 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7490 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7491 D3DDECL_END()
7493 IDirect3DVertexDeclaration9 *vdecl = NULL;
7494 IDirect3DVertexBuffer9 *buffer = NULL;
7495 IDirect3DVertexShader9 *shader;
7496 DWORD shader_code[] = {
7497 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7498 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7499 0x90e40001, 0x0000ffff
7501 struct vertex_float16color quad[] = {
7502 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7503 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7504 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7505 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7507 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7508 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7509 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7510 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7512 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7513 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7514 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7515 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7517 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7518 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7519 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7520 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7523 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7524 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7526 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7527 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7528 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7529 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7530 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7531 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7533 hr = IDirect3DDevice9_BeginScene(device);
7534 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7535 if(SUCCEEDED(hr)) {
7536 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7537 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7539 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7541 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7543 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7545 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7547 hr = IDirect3DDevice9_EndScene(device);
7548 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7550 color = getPixelColor(device, 480, 360);
7551 ok(color == 0x00ff0000,
7552 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7553 color = getPixelColor(device, 160, 120);
7554 ok(color == 0x00000000,
7555 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7556 color = getPixelColor(device, 160, 360);
7557 ok(color == 0x0000ff00,
7558 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7559 color = getPixelColor(device, 480, 120);
7560 ok(color == 0x000000ff,
7561 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7562 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7564 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7565 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7567 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7568 D3DPOOL_MANAGED, &buffer, NULL);
7569 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7570 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7571 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7572 memcpy(data, quad, sizeof(quad));
7573 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7574 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7575 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7576 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7578 hr = IDirect3DDevice9_BeginScene(device);
7579 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7580 if(SUCCEEDED(hr)) {
7581 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7582 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7583 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7584 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7585 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7586 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7587 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7588 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7590 hr = IDirect3DDevice9_EndScene(device);
7591 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7594 color = getPixelColor(device, 480, 360);
7595 ok(color == 0x00ff0000,
7596 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7597 color = getPixelColor(device, 160, 120);
7598 ok(color == 0x00000000,
7599 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7600 color = getPixelColor(device, 160, 360);
7601 ok(color == 0x0000ff00,
7602 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7603 color = getPixelColor(device, 480, 120);
7604 ok(color == 0x000000ff,
7605 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7606 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7608 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7609 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7610 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7611 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7612 IDirect3DDevice9_SetVertexShader(device, NULL);
7613 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7615 IDirect3DVertexDeclaration9_Release(vdecl);
7616 IDirect3DVertexShader9_Release(shader);
7617 IDirect3DVertexBuffer9_Release(buffer);
7620 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7622 D3DCAPS9 caps;
7623 IDirect3DTexture9 *texture;
7624 HRESULT hr;
7625 D3DLOCKED_RECT rect;
7626 unsigned int x, y;
7627 DWORD *dst, color;
7628 const float quad[] = {
7629 -1.0, -1.0, 0.1, -0.2, -0.2,
7630 1.0, -1.0, 0.1, 1.2, -0.2,
7631 -1.0, 1.0, 0.1, -0.2, 1.2,
7632 1.0, 1.0, 0.1, 1.2, 1.2
7634 memset(&caps, 0, sizeof(caps));
7636 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7637 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7638 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7639 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7640 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7641 "Card has conditional NP2 support without power of two restriction set\n");
7642 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7643 return;
7644 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7645 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7646 return;
7649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7650 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7652 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7653 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7655 memset(&rect, 0, sizeof(rect));
7656 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7657 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7658 for(y = 0; y < 10; y++) {
7659 for(x = 0; x < 10; x++) {
7660 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7661 if(x == 0 || x == 9 || y == 0 || y == 9) {
7662 *dst = 0x00ff0000;
7663 } else {
7664 *dst = 0x000000ff;
7668 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7669 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7671 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7672 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7673 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7675 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7676 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7677 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7680 hr = IDirect3DDevice9_BeginScene(device);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7682 if(SUCCEEDED(hr)) {
7683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7684 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7686 hr = IDirect3DDevice9_EndScene(device);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7690 color = getPixelColor(device, 1, 1);
7691 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7692 color = getPixelColor(device, 639, 479);
7693 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7695 color = getPixelColor(device, 135, 101);
7696 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7697 color = getPixelColor(device, 140, 101);
7698 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7699 color = getPixelColor(device, 135, 105);
7700 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7701 color = getPixelColor(device, 140, 105);
7702 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7704 color = getPixelColor(device, 135, 376);
7705 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7706 color = getPixelColor(device, 140, 376);
7707 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7708 color = getPixelColor(device, 135, 379);
7709 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7710 color = getPixelColor(device, 140, 379);
7711 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7713 color = getPixelColor(device, 500, 101);
7714 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7715 color = getPixelColor(device, 504, 101);
7716 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7717 color = getPixelColor(device, 500, 105);
7718 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7719 color = getPixelColor(device, 504, 105);
7720 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7722 color = getPixelColor(device, 500, 376);
7723 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7724 color = getPixelColor(device, 504, 376);
7725 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7726 color = getPixelColor(device, 500, 380);
7727 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7728 color = getPixelColor(device, 504, 380);
7729 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7731 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7733 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7734 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7735 IDirect3DTexture9_Release(texture);
7738 static void vFace_register_test(IDirect3DDevice9 *device)
7740 HRESULT hr;
7741 DWORD color;
7742 const DWORD shader_code[] = {
7743 0xffff0300, /* ps_3_0 */
7744 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7745 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7746 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7747 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7748 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7749 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7750 0x0000ffff /* END */
7752 const DWORD vshader_code[] = {
7753 0xfffe0300, /* vs_3_0 */
7754 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7755 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7756 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7757 0x0000ffff /* end */
7759 IDirect3DPixelShader9 *shader;
7760 IDirect3DVertexShader9 *vshader;
7761 IDirect3DTexture9 *texture;
7762 IDirect3DSurface9 *surface, *backbuffer;
7763 const float quad[] = {
7764 -1.0, -1.0, 0.1,
7765 1.0, -1.0, 0.1,
7766 -1.0, 0.0, 0.1,
7768 1.0, -1.0, 0.1,
7769 1.0, 0.0, 0.1,
7770 -1.0, 0.0, 0.1,
7772 -1.0, 0.0, 0.1,
7773 -1.0, 1.0, 0.1,
7774 1.0, 0.0, 0.1,
7776 1.0, 0.0, 0.1,
7777 -1.0, 1.0, 0.1,
7778 1.0, 1.0, 0.1,
7780 const float blit[] = {
7781 0.0, -1.0, 0.1, 0.0, 0.0,
7782 1.0, -1.0, 0.1, 1.0, 0.0,
7783 0.0, 1.0, 0.1, 0.0, 1.0,
7784 1.0, 1.0, 0.1, 1.0, 1.0,
7787 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7788 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7789 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7790 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7791 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7792 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7793 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7794 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7795 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7796 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7797 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7798 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7799 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7800 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7801 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7802 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7804 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7805 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7807 hr = IDirect3DDevice9_BeginScene(device);
7808 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7809 if(SUCCEEDED(hr)) {
7810 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7811 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7812 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7813 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7814 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7816 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7817 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7818 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7819 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7820 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7822 /* Blit the texture onto the back buffer to make it visible */
7823 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7824 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7825 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7826 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7827 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7828 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7829 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7830 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7831 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7832 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7833 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7834 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7837 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7839 hr = IDirect3DDevice9_EndScene(device);
7840 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7843 color = getPixelColor(device, 160, 360);
7844 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7845 color = getPixelColor(device, 160, 120);
7846 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7847 color = getPixelColor(device, 480, 360);
7848 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7849 color = getPixelColor(device, 480, 120);
7850 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7851 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7853 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7854 IDirect3DDevice9_SetTexture(device, 0, NULL);
7855 IDirect3DPixelShader9_Release(shader);
7856 IDirect3DVertexShader9_Release(vshader);
7857 IDirect3DSurface9_Release(surface);
7858 IDirect3DSurface9_Release(backbuffer);
7859 IDirect3DTexture9_Release(texture);
7862 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7864 HRESULT hr;
7865 DWORD color;
7866 int i;
7867 D3DCAPS9 caps;
7868 BOOL L6V5U5_supported = FALSE;
7869 IDirect3DTexture9 *tex1, *tex2;
7870 D3DLOCKED_RECT locked_rect;
7872 static const float quad[][7] = {
7873 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7874 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7875 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7876 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7879 static const D3DVERTEXELEMENT9 decl_elements[] = {
7880 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7881 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7882 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7883 D3DDECL_END()
7886 /* use asymmetric matrix to test loading */
7887 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7888 float scale, offset;
7890 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7891 IDirect3DTexture9 *texture = NULL;
7893 memset(&caps, 0, sizeof(caps));
7894 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7895 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7896 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7897 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7898 return;
7899 } else {
7900 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7901 * They report that it is not supported, but after that bump mapping works properly. So just test
7902 * if the format is generally supported, and check the BUMPENVMAP flag
7904 IDirect3D9 *d3d9;
7906 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7907 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7908 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7909 L6V5U5_supported = SUCCEEDED(hr);
7910 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7911 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7912 IDirect3D9_Release(d3d9);
7913 if(FAILED(hr)) {
7914 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7915 return;
7919 /* Generate the textures */
7920 generate_bumpmap_textures(device);
7922 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7923 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7924 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7925 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7927 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7928 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7929 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7931 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7932 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7934 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7935 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7936 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7938 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7939 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7940 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7941 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7942 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7943 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7945 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7946 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7948 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7949 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7951 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7952 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7955 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7956 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7957 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7958 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7960 hr = IDirect3DDevice9_BeginScene(device);
7961 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7964 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7966 hr = IDirect3DDevice9_EndScene(device);
7967 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7969 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7970 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7971 * But since testing the color match is not the purpose of the test don't be too picky
7973 color = getPixelColor(device, 320-32, 240);
7974 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7975 color = getPixelColor(device, 320+32, 240);
7976 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7977 color = getPixelColor(device, 320, 240-32);
7978 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7979 color = getPixelColor(device, 320, 240+32);
7980 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7981 color = getPixelColor(device, 320, 240);
7982 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7983 color = getPixelColor(device, 320+32, 240+32);
7984 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7985 color = getPixelColor(device, 320-32, 240+32);
7986 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7987 color = getPixelColor(device, 320+32, 240-32);
7988 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7989 color = getPixelColor(device, 320-32, 240-32);
7990 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7992 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7994 for(i = 0; i < 2; i++) {
7995 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7996 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7997 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7998 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7999 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8000 IDirect3DTexture9_Release(texture); /* To destroy it */
8003 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8004 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8005 goto cleanup;
8007 if(L6V5U5_supported == FALSE) {
8008 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8009 goto cleanup;
8012 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8013 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8014 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8015 * would only make this test more complicated
8017 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8018 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8019 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8020 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8022 memset(&locked_rect, 0, sizeof(locked_rect));
8023 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8024 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8025 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8026 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8027 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8029 memset(&locked_rect, 0, sizeof(locked_rect));
8030 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8031 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8032 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8033 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8034 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8036 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8037 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8038 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8039 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8041 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8042 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8043 scale = 2.0;
8044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8045 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8046 offset = 0.1;
8047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8048 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8050 hr = IDirect3DDevice9_BeginScene(device);
8051 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8052 if(SUCCEEDED(hr)) {
8053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8054 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8055 hr = IDirect3DDevice9_EndScene(device);
8056 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8059 color = getPixelColor(device, 320, 240);
8060 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8061 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8062 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8064 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8065 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8066 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8068 /* Check a result scale factor > 1.0 */
8069 scale = 10;
8070 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8071 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8072 offset = 10;
8073 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8074 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8076 hr = IDirect3DDevice9_BeginScene(device);
8077 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8078 if(SUCCEEDED(hr)) {
8079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8080 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8081 hr = IDirect3DDevice9_EndScene(device);
8082 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8084 color = getPixelColor(device, 320, 240);
8085 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8086 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8087 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8089 /* Check clamping in the scale factor calculation */
8090 scale = 1000;
8091 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8092 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8093 offset = -1;
8094 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8095 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8097 hr = IDirect3DDevice9_BeginScene(device);
8098 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8099 if(SUCCEEDED(hr)) {
8100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8101 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8102 hr = IDirect3DDevice9_EndScene(device);
8103 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8105 color = getPixelColor(device, 320, 240);
8106 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8107 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8108 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8110 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8111 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8112 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8115 IDirect3DTexture9_Release(tex1);
8116 IDirect3DTexture9_Release(tex2);
8118 cleanup:
8119 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8120 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8121 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8122 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8124 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8125 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8126 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8129 static void stencil_cull_test(IDirect3DDevice9 *device) {
8130 HRESULT hr;
8131 IDirect3DSurface9 *depthstencil = NULL;
8132 D3DSURFACE_DESC desc;
8133 float quad1[] = {
8134 -1.0, -1.0, 0.1,
8135 0.0, -1.0, 0.1,
8136 -1.0, 0.0, 0.1,
8137 0.0, 0.0, 0.1,
8139 float quad2[] = {
8140 0.0, -1.0, 0.1,
8141 1.0, -1.0, 0.1,
8142 0.0, 0.0, 0.1,
8143 1.0, 0.0, 0.1,
8145 float quad3[] = {
8146 0.0, 0.0, 0.1,
8147 1.0, 0.0, 0.1,
8148 0.0, 1.0, 0.1,
8149 1.0, 1.0, 0.1,
8151 float quad4[] = {
8152 -1.0, 0.0, 0.1,
8153 0.0, 0.0, 0.1,
8154 -1.0, 1.0, 0.1,
8155 0.0, 1.0, 0.1,
8157 struct vertex painter[] = {
8158 {-1.0, -1.0, 0.0, 0x00000000},
8159 { 1.0, -1.0, 0.0, 0x00000000},
8160 {-1.0, 1.0, 0.0, 0x00000000},
8161 { 1.0, 1.0, 0.0, 0x00000000},
8163 WORD indices_cw[] = {0, 1, 3};
8164 WORD indices_ccw[] = {0, 2, 3};
8165 unsigned int i;
8166 DWORD color;
8168 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8169 if(depthstencil == NULL) {
8170 skip("No depth stencil buffer\n");
8171 return;
8173 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8174 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8175 IDirect3DSurface9_Release(depthstencil);
8176 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8177 skip("No 4 or 8 bit stencil surface\n");
8178 return;
8181 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8182 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8183 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8186 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8187 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8188 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8190 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8192 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8195 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8199 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8204 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8206 /* First pass: Fill the stencil buffer with some values... */
8207 hr = IDirect3DDevice9_BeginScene(device);
8208 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8209 if(SUCCEEDED(hr))
8211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8212 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8213 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8214 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8215 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8216 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8217 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8218 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8221 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8222 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8223 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8224 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8225 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8226 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8227 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8228 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8229 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8233 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8234 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8235 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8236 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8237 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8238 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8242 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8243 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8244 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8245 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8246 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8247 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8249 hr = IDirect3DDevice9_EndScene(device);
8250 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8253 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8254 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8255 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8257 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8258 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8259 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8265 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8267 /* 2nd pass: Make the stencil values visible */
8268 hr = IDirect3DDevice9_BeginScene(device);
8269 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8270 if(SUCCEEDED(hr))
8272 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8273 for(i = 0; i < 16; i++) {
8274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8277 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8278 painter[1].diffuse = (i * 16);
8279 painter[2].diffuse = (i * 16);
8280 painter[3].diffuse = (i * 16);
8281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8282 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8284 hr = IDirect3DDevice9_EndScene(device);
8285 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8291 color = getPixelColor(device, 160, 420);
8292 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8293 color = getPixelColor(device, 160, 300);
8294 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8296 color = getPixelColor(device, 480, 420);
8297 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8298 color = getPixelColor(device, 480, 300);
8299 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8301 color = getPixelColor(device, 160, 180);
8302 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8303 color = getPixelColor(device, 160, 60);
8304 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8306 color = getPixelColor(device, 480, 180);
8307 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8308 color = getPixelColor(device, 480, 60);
8309 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8311 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8312 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8315 static void vpos_register_test(IDirect3DDevice9 *device)
8317 HRESULT hr;
8318 DWORD color;
8319 const DWORD shader_code[] = {
8320 0xffff0300, /* ps_3_0 */
8321 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8322 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8323 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8324 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8325 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8326 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8327 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8328 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8329 0x0000ffff /* end */
8331 const DWORD shader_frac_code[] = {
8332 0xffff0300, /* ps_3_0 */
8333 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8334 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8335 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8336 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8337 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8338 0x0000ffff /* end */
8340 const DWORD vshader_code[] = {
8341 0xfffe0300, /* vs_3_0 */
8342 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8343 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8344 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8345 0x0000ffff /* end */
8347 IDirect3DVertexShader9 *vshader;
8348 IDirect3DPixelShader9 *shader, *shader_frac;
8349 IDirect3DSurface9 *surface = NULL, *backbuffer;
8350 const float quad[] = {
8351 -1.0, -1.0, 0.1, 0.0, 0.0,
8352 1.0, -1.0, 0.1, 1.0, 0.0,
8353 -1.0, 1.0, 0.1, 0.0, 1.0,
8354 1.0, 1.0, 0.1, 1.0, 1.0,
8356 D3DLOCKED_RECT lr;
8357 float constant[4] = {1.0, 0.0, 320, 240};
8358 DWORD *pos;
8360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8361 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8362 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8363 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8364 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8365 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8366 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8367 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8368 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8369 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8370 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8372 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8373 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8374 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8375 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8377 hr = IDirect3DDevice9_BeginScene(device);
8378 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8379 if(SUCCEEDED(hr)) {
8380 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8381 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8383 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8384 hr = IDirect3DDevice9_EndScene(device);
8385 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8388 /* This has to be pixel exact */
8389 color = getPixelColor(device, 319, 239);
8390 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8391 color = getPixelColor(device, 320, 239);
8392 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8393 color = getPixelColor(device, 319, 240);
8394 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8395 color = getPixelColor(device, 320, 240);
8396 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8397 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8399 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8400 &surface, NULL);
8401 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8402 hr = IDirect3DDevice9_BeginScene(device);
8403 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8404 if(SUCCEEDED(hr)) {
8405 constant[2] = 16; constant[3] = 16;
8406 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8407 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8408 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8409 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8412 hr = IDirect3DDevice9_EndScene(device);
8413 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8415 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8416 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8418 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8419 color = *pos & 0x00ffffff;
8420 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8421 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8422 color = *pos & 0x00ffffff;
8423 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8424 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8425 color = *pos & 0x00ffffff;
8426 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8427 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8428 color = *pos & 0x00ffffff;
8429 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8431 hr = IDirect3DSurface9_UnlockRect(surface);
8432 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8434 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8435 * have full control over the multisampling setting inside this test
8437 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8438 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8439 hr = IDirect3DDevice9_BeginScene(device);
8440 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8441 if(SUCCEEDED(hr)) {
8442 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8443 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8445 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8446 hr = IDirect3DDevice9_EndScene(device);
8447 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8449 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8450 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8452 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8453 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8455 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8456 color = *pos & 0x00ffffff;
8457 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8459 hr = IDirect3DSurface9_UnlockRect(surface);
8460 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8462 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8463 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8464 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8465 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8466 IDirect3DPixelShader9_Release(shader);
8467 IDirect3DPixelShader9_Release(shader_frac);
8468 IDirect3DVertexShader9_Release(vshader);
8469 if(surface) IDirect3DSurface9_Release(surface);
8470 IDirect3DSurface9_Release(backbuffer);
8473 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8475 D3DCOLOR color;
8477 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8478 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8479 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8480 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8481 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8483 ++r;
8484 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8485 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8486 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8487 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8488 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8490 return TRUE;
8493 static void pointsize_test(IDirect3DDevice9 *device)
8495 HRESULT hr;
8496 D3DCAPS9 caps;
8497 D3DMATRIX matrix;
8498 D3DMATRIX identity;
8499 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8500 DWORD color;
8501 IDirect3DSurface9 *rt, *backbuffer;
8502 IDirect3DTexture9 *tex1, *tex2;
8503 RECT rect = {0, 0, 128, 128};
8504 D3DLOCKED_RECT lr;
8505 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8506 0x00000000, 0x00000000};
8507 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8508 0x00000000, 0x0000ff00};
8510 const float vertices[] = {
8511 64, 64, 0.1,
8512 128, 64, 0.1,
8513 192, 64, 0.1,
8514 256, 64, 0.1,
8515 320, 64, 0.1,
8516 384, 64, 0.1,
8517 448, 64, 0.1,
8518 512, 64, 0.1,
8521 /* 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 */
8522 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;
8523 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;
8524 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;
8525 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;
8527 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;
8528 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;
8529 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;
8530 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;
8532 memset(&caps, 0, sizeof(caps));
8533 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8534 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8535 if(caps.MaxPointSize < 32.0) {
8536 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8537 return;
8540 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8541 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8542 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8543 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8544 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8545 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8546 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8547 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8549 hr = IDirect3DDevice9_BeginScene(device);
8550 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8551 if (SUCCEEDED(hr))
8553 ptsize = 15.0;
8554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8555 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8556 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8557 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8559 ptsize = 31.0;
8560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8561 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8563 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8565 ptsize = 30.75;
8566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8567 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8569 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8571 if (caps.MaxPointSize >= 63.0)
8573 ptsize = 63.0;
8574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8577 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8579 ptsize = 62.75;
8580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8581 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8583 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8586 ptsize = 1.0;
8587 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8588 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8590 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8592 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8593 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8594 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8595 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8597 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8598 ptsize = 15.0;
8599 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8600 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8601 ptsize = 1.0;
8602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8603 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8604 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8605 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8608 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8610 /* pointsize < pointsize_min < pointsize_max?
8611 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8612 ptsize = 1.0;
8613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8614 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8615 ptsize = 15.0;
8616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8617 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8619 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8621 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8622 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8624 hr = IDirect3DDevice9_EndScene(device);
8625 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8628 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8629 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8630 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8632 if (caps.MaxPointSize >= 63.0)
8634 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8635 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8638 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8639 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8640 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8641 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8642 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8644 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8646 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8647 * generates texture coordinates for the point(result: Yes, it does)
8649 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8650 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8651 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8654 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8656 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8657 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8658 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8659 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8660 memset(&lr, 0, sizeof(lr));
8661 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8662 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8663 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8664 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8665 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8666 memset(&lr, 0, sizeof(lr));
8667 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8668 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8669 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8670 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8671 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8672 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8674 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8675 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8676 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8677 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8678 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8679 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8680 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8681 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8682 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8683 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8684 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8685 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8688 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8689 ptsize = 32.0;
8690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8693 hr = IDirect3DDevice9_BeginScene(device);
8694 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8695 if(SUCCEEDED(hr))
8697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8698 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8699 hr = IDirect3DDevice9_EndScene(device);
8700 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8703 color = getPixelColor(device, 64-4, 64-4);
8704 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8705 color = getPixelColor(device, 64-4, 64+4);
8706 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8707 color = getPixelColor(device, 64+4, 64+4);
8708 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8709 color = getPixelColor(device, 64+4, 64-4);
8710 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8711 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8713 U(matrix).m[0][0] = 1.0f / 64.0f;
8714 U(matrix).m[1][1] = -1.0f / 64.0f;
8715 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8716 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8718 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8719 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8721 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8722 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8723 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8725 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8726 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8727 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8728 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8730 hr = IDirect3DDevice9_BeginScene(device);
8731 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8733 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8734 hr = IDirect3DDevice9_EndScene(device);
8735 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8737 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8738 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8739 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8740 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8741 IDirect3DSurface9_Release(backbuffer);
8742 IDirect3DSurface9_Release(rt);
8744 color = getPixelColor(device, 64-4, 64-4);
8745 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8746 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8747 color = getPixelColor(device, 64+4, 64-4);
8748 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8749 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8750 color = getPixelColor(device, 64-4, 64+4);
8751 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8752 "Expected color 0x00000000, got 0x%08x.\n", color);
8753 color = getPixelColor(device, 64+4, 64+4);
8754 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8755 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8757 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8758 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8760 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8761 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8762 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8763 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8764 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8765 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8766 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8767 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8768 IDirect3DTexture9_Release(tex1);
8769 IDirect3DTexture9_Release(tex2);
8771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8772 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8774 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8775 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8776 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8779 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8781 static const DWORD vshader_code[] =
8783 0xfffe0300, /* vs_3_0 */
8784 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8785 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8786 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8787 0x0000ffff /* end */
8789 static const DWORD pshader_code1[] =
8791 0xffff0300, /* ps_3_0 */
8792 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8793 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8794 0x0000ffff /* end */
8796 static const DWORD pshader_code2[] =
8798 0xffff0300, /* ps_3_0 */
8799 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8800 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8801 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8802 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8803 0x0000ffff /* end */
8806 HRESULT hr;
8807 IDirect3DVertexShader9 *vs;
8808 IDirect3DPixelShader9 *ps1, *ps2;
8809 IDirect3DTexture9 *tex1, *tex2;
8810 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8811 D3DCAPS9 caps;
8812 DWORD color;
8813 UINT i, j;
8814 float quad[] = {
8815 -1.0, -1.0, 0.1,
8816 1.0, -1.0, 0.1,
8817 -1.0, 1.0, 0.1,
8818 1.0, 1.0, 0.1,
8820 float texquad[] = {
8821 -1.0, -1.0, 0.1, 0.0, 0.0,
8822 0.0, -1.0, 0.1, 1.0, 0.0,
8823 -1.0, 1.0, 0.1, 0.0, 1.0,
8824 0.0, 1.0, 0.1, 1.0, 1.0,
8826 0.0, -1.0, 0.1, 0.0, 0.0,
8827 1.0, -1.0, 0.1, 1.0, 0.0,
8828 0.0, 1.0, 0.1, 0.0, 1.0,
8829 1.0, 1.0, 0.1, 1.0, 1.0,
8832 memset(&caps, 0, sizeof(caps));
8833 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8834 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8835 if(caps.NumSimultaneousRTs < 2) {
8836 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8837 return;
8840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8841 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8843 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8844 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8845 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8847 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8848 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8849 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8850 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8851 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8852 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8853 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8854 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8855 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8856 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8857 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8858 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8860 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8861 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8862 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8863 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8864 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8865 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8867 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8868 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8869 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8870 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8871 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8872 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8874 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8877 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8878 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8879 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8880 color = getPixelColorFromSurface(readback, 8, 8);
8881 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8882 "Expected color 0x000000ff, got 0x%08x.\n", color);
8883 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8884 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8885 color = getPixelColorFromSurface(readback, 8, 8);
8886 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8887 "Expected color 0x000000ff, got 0x%08x.\n", color);
8889 /* Render targets not written by the pixel shader should be unmodified. */
8890 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8891 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8892 hr = IDirect3DDevice9_BeginScene(device);
8893 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8895 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8896 hr = IDirect3DDevice9_EndScene(device);
8897 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8898 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8899 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8900 color = getPixelColorFromSurface(readback, 8, 8);
8901 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8902 "Expected color 0xff00ff00, got 0x%08x.\n", color);
8903 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8904 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8905 for (i = 6; i < 10; ++i)
8907 for (j = 6; j < 10; ++j)
8909 color = getPixelColorFromSurface(readback, j, i);
8910 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8911 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
8915 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8916 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8917 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8918 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8919 color = getPixelColorFromSurface(readback, 8, 8);
8920 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8921 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8922 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8923 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8924 color = getPixelColorFromSurface(readback, 8, 8);
8925 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8926 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8928 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
8929 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8931 hr = IDirect3DDevice9_BeginScene(device);
8932 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8933 if(SUCCEEDED(hr)) {
8934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8935 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8937 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8938 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8939 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8940 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8941 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8942 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8943 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8944 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8946 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8948 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8951 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8953 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8954 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8956 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8958 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8959 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8961 hr = IDirect3DDevice9_EndScene(device);
8962 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8965 color = getPixelColor(device, 160, 240);
8966 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8967 color = getPixelColor(device, 480, 240);
8968 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8969 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8971 IDirect3DPixelShader9_Release(ps2);
8972 IDirect3DPixelShader9_Release(ps1);
8973 IDirect3DVertexShader9_Release(vs);
8974 IDirect3DTexture9_Release(tex1);
8975 IDirect3DTexture9_Release(tex2);
8976 IDirect3DSurface9_Release(surf1);
8977 IDirect3DSurface9_Release(surf2);
8978 IDirect3DSurface9_Release(backbuf);
8979 IDirect3DSurface9_Release(readback);
8982 struct formats {
8983 const char *fmtName;
8984 D3DFORMAT textureFormat;
8985 DWORD resultColorBlending;
8986 DWORD resultColorNoBlending;
8989 static const struct formats test_formats[] = {
8990 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8991 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8992 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8993 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8994 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8995 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8996 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8997 { NULL, 0 }
9000 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9002 HRESULT hr;
9003 IDirect3DTexture9 *offscreenTexture = NULL;
9004 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9005 IDirect3D9 *d3d = NULL;
9006 DWORD color;
9007 DWORD r0, g0, b0, r1, g1, b1;
9008 int fmt_index;
9010 static const float quad[][5] = {
9011 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9012 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9013 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9014 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9017 /* Quad with R=0x10, G=0x20 */
9018 static const struct vertex quad1[] = {
9019 {-1.0f, -1.0f, 0.1f, 0x80102000},
9020 {-1.0f, 1.0f, 0.1f, 0x80102000},
9021 { 1.0f, -1.0f, 0.1f, 0x80102000},
9022 { 1.0f, 1.0f, 0.1f, 0x80102000},
9025 /* Quad with R=0x20, G=0x10 */
9026 static const struct vertex quad2[] = {
9027 {-1.0f, -1.0f, 0.1f, 0x80201000},
9028 {-1.0f, 1.0f, 0.1f, 0x80201000},
9029 { 1.0f, -1.0f, 0.1f, 0x80201000},
9030 { 1.0f, 1.0f, 0.1f, 0x80201000},
9033 IDirect3DDevice9_GetDirect3D(device, &d3d);
9035 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9036 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9037 if(!backbuffer) {
9038 goto out;
9041 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9043 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9045 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9046 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9048 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9049 continue;
9052 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9053 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9055 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9056 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9057 if(!offscreenTexture) {
9058 continue;
9061 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9062 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9063 if(!offscreen) {
9064 continue;
9067 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9068 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9070 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9071 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9072 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9073 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9074 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9075 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9076 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9077 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9079 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9081 /* Below we will draw two quads with different colors and try to blend them together.
9082 * The result color is compared with the expected outcome.
9084 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9085 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9086 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9087 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9088 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9091 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9093 /* Draw a quad using color 0x0010200 */
9094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9097 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9099 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9101 /* Draw a quad using color 0x0020100 */
9102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9103 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9105 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9107 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9109 /* We don't want to blend the result on the backbuffer */
9110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9113 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9114 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9115 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9116 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9117 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9119 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9120 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9122 /* This time with the texture */
9123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9124 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9126 IDirect3DDevice9_EndScene(device);
9129 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9130 /* Compare the color of the center quad with our expectation */
9131 color = getPixelColor(device, 320, 240);
9132 r0 = (color & 0x00ff0000) >> 16;
9133 g0 = (color & 0x0000ff00) >> 8;
9134 b0 = (color & 0x000000ff) >> 0;
9136 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9137 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9138 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9140 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9141 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9142 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9143 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9144 } else {
9145 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9146 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9147 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9148 color = getPixelColor(device, 320, 240);
9149 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);
9151 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9153 IDirect3DDevice9_SetTexture(device, 0, NULL);
9154 if(offscreenTexture) {
9155 IDirect3DTexture9_Release(offscreenTexture);
9157 if(offscreen) {
9158 IDirect3DSurface9_Release(offscreen);
9162 out:
9163 /* restore things */
9164 if(backbuffer) {
9165 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9166 IDirect3DSurface9_Release(backbuffer);
9170 static void tssargtemp_test(IDirect3DDevice9 *device)
9172 HRESULT hr;
9173 DWORD color;
9174 static const struct vertex quad[] = {
9175 {-1.0, -1.0, 0.1, 0x00ff0000},
9176 { 1.0, -1.0, 0.1, 0x00ff0000},
9177 {-1.0, 1.0, 0.1, 0x00ff0000},
9178 { 1.0, 1.0, 0.1, 0x00ff0000}
9180 D3DCAPS9 caps;
9182 memset(&caps, 0, sizeof(caps));
9183 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9184 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9185 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9186 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9187 return;
9190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9191 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9193 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9194 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9195 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9196 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9198 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9199 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9200 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9201 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9202 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9203 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9205 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9206 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9207 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9208 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9209 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9210 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9212 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9213 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9216 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9217 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9218 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9220 hr = IDirect3DDevice9_BeginScene(device);
9221 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9222 if(SUCCEEDED(hr)) {
9223 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9224 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9225 hr = IDirect3DDevice9_EndScene(device);
9226 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9228 color = getPixelColor(device, 320, 240);
9229 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9230 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9232 /* Set stage 1 back to default */
9233 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9234 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9235 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9236 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9237 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9238 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9239 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9240 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9241 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9242 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9245 struct testdata
9247 DWORD idxVertex; /* number of instances in the first stream */
9248 DWORD idxColor; /* number of instances in the second stream */
9249 DWORD idxInstance; /* should be 1 ?? */
9250 DWORD color1; /* color 1 instance */
9251 DWORD color2; /* color 2 instance */
9252 DWORD color3; /* color 3 instance */
9253 DWORD color4; /* color 4 instance */
9254 WORD strVertex; /* specify which stream to use 0-2*/
9255 WORD strColor;
9256 WORD strInstance;
9259 static const struct testdata testcases[]=
9261 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9262 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9263 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9264 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9265 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9266 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9267 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9268 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9269 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9270 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9271 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9272 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9273 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9274 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9276 This draws one instance on some machines, no instance on others
9277 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9280 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9281 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9285 /* Drawing Indexed Geometry with instances*/
9286 static void stream_test(IDirect3DDevice9 *device)
9288 IDirect3DVertexBuffer9 *vb = NULL;
9289 IDirect3DVertexBuffer9 *vb2 = NULL;
9290 IDirect3DVertexBuffer9 *vb3 = NULL;
9291 IDirect3DIndexBuffer9 *ib = NULL;
9292 IDirect3DVertexDeclaration9 *pDecl = NULL;
9293 IDirect3DVertexShader9 *shader = NULL;
9294 HRESULT hr;
9295 BYTE *data;
9296 DWORD color;
9297 DWORD ind;
9298 unsigned i;
9300 const DWORD shader_code[] =
9302 0xfffe0101, /* vs_1_1 */
9303 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9304 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9305 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9306 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9307 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9308 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9309 0x0000ffff
9312 const float quad[][3] =
9314 {-0.5f, -0.5f, 1.1f}, /*0 */
9315 {-0.5f, 0.5f, 1.1f}, /*1 */
9316 { 0.5f, -0.5f, 1.1f}, /*2 */
9317 { 0.5f, 0.5f, 1.1f}, /*3 */
9320 const float vertcolor[][4] =
9322 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9323 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9324 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9325 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9328 /* 4 position for 4 instances */
9329 const float instancepos[][3] =
9331 {-0.6f,-0.6f, 0.0f},
9332 { 0.6f,-0.6f, 0.0f},
9333 { 0.6f, 0.6f, 0.0f},
9334 {-0.6f, 0.6f, 0.0f},
9337 short indices[] = {0, 1, 2, 1, 2, 3};
9339 D3DVERTEXELEMENT9 decl[] =
9341 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9342 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9343 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9344 D3DDECL_END()
9347 /* set the default value because it isn't done in wine? */
9348 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9349 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9351 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9352 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9353 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9355 /* check wrong cases */
9356 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9357 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9358 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9359 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9360 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9361 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9362 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9363 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9364 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9365 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9366 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9367 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9368 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9369 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9370 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9371 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9372 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9373 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9374 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9375 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9377 /* set the default value back */
9378 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9379 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9381 /* create all VertexBuffers*/
9382 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9383 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9384 if(!vb) {
9385 skip("Failed to create a vertex buffer\n");
9386 return;
9388 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9389 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9390 if(!vb2) {
9391 skip("Failed to create a vertex buffer\n");
9392 goto out;
9394 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9395 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9396 if(!vb3) {
9397 skip("Failed to create a vertex buffer\n");
9398 goto out;
9401 /* create IndexBuffer*/
9402 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9403 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9404 if(!ib) {
9405 skip("Failed to create a index buffer\n");
9406 goto out;
9409 /* copy all Buffers (Vertex + Index)*/
9410 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9411 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9412 memcpy(data, quad, sizeof(quad));
9413 hr = IDirect3DVertexBuffer9_Unlock(vb);
9414 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9415 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9416 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9417 memcpy(data, vertcolor, sizeof(vertcolor));
9418 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9419 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9420 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9421 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9422 memcpy(data, instancepos, sizeof(instancepos));
9423 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9424 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9425 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9426 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9427 memcpy(data, indices, sizeof(indices));
9428 hr = IDirect3DIndexBuffer9_Unlock(ib);
9429 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9431 /* create VertexShader */
9432 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9433 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9434 if(!shader) {
9435 skip("Failed to create a vetex shader\n");
9436 goto out;
9439 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9440 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9442 hr = IDirect3DDevice9_SetIndices(device, ib);
9443 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9445 /* run all tests */
9446 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9448 struct testdata act = testcases[i];
9449 decl[0].Stream = act.strVertex;
9450 decl[1].Stream = act.strColor;
9451 decl[2].Stream = act.strInstance;
9452 /* create VertexDeclarations */
9453 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9454 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9456 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9457 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9459 hr = IDirect3DDevice9_BeginScene(device);
9460 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9461 if(SUCCEEDED(hr))
9463 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9466 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9467 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9468 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9469 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9471 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9472 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9473 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9474 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9476 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9477 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9478 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9479 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9481 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9482 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9483 hr = IDirect3DDevice9_EndScene(device);
9484 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9486 /* set all StreamSource && StreamSourceFreq back to default */
9487 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9488 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9489 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9490 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9491 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9492 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9493 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9494 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9495 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9496 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9497 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9498 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9501 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9502 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9504 color = getPixelColor(device, 160, 360);
9505 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9506 color = getPixelColor(device, 480, 360);
9507 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9508 color = getPixelColor(device, 480, 120);
9509 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9510 color = getPixelColor(device, 160, 120);
9511 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9513 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9514 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9517 hr = IDirect3DDevice9_SetIndices(device, NULL);
9518 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9520 out:
9521 if(vb) IDirect3DVertexBuffer9_Release(vb);
9522 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9523 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9524 if(ib)IDirect3DIndexBuffer9_Release(ib);
9525 if(shader)IDirect3DVertexShader9_Release(shader);
9528 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9529 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9530 IDirect3DTexture9 *dsttex = NULL;
9531 HRESULT hr;
9532 DWORD color;
9533 D3DRECT r1 = {0, 0, 50, 50 };
9534 D3DRECT r2 = {50, 0, 100, 50 };
9535 D3DRECT r3 = {50, 50, 100, 100};
9536 D3DRECT r4 = {0, 50, 50, 100};
9537 const float quad[] = {
9538 -1.0, -1.0, 0.1, 0.0, 0.0,
9539 1.0, -1.0, 0.1, 1.0, 0.0,
9540 -1.0, 1.0, 0.1, 0.0, 1.0,
9541 1.0, 1.0, 0.1, 1.0, 1.0,
9544 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9545 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9547 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9548 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9549 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9550 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9552 if(!src || !dsttex) {
9553 skip("One or more test resources could not be created\n");
9554 goto cleanup;
9557 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9558 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9560 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9561 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9563 /* Clear the StretchRect destination for debugging */
9564 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9565 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9566 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9567 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9569 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9570 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9572 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9573 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9574 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9575 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9576 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9577 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9578 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9579 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9581 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9582 * the target -> texture GL blit path
9584 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9585 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9586 IDirect3DSurface9_Release(dst);
9588 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9589 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9591 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9592 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9593 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9594 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9595 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9596 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9597 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9598 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9600 hr = IDirect3DDevice9_BeginScene(device);
9601 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9602 if(SUCCEEDED(hr)) {
9603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9604 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9605 hr = IDirect3DDevice9_EndScene(device);
9606 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9609 color = getPixelColor(device, 160, 360);
9610 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9611 color = getPixelColor(device, 480, 360);
9612 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9613 color = getPixelColor(device, 480, 120);
9614 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9615 color = getPixelColor(device, 160, 120);
9616 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9618 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9620 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9621 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9622 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9623 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9625 cleanup:
9626 if(src) IDirect3DSurface9_Release(src);
9627 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9628 if(dsttex) IDirect3DTexture9_Release(dsttex);
9631 static void texop_test(IDirect3DDevice9 *device)
9633 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9634 IDirect3DTexture9 *texture = NULL;
9635 D3DLOCKED_RECT locked_rect;
9636 D3DCOLOR color;
9637 D3DCAPS9 caps;
9638 HRESULT hr;
9639 unsigned i;
9641 static const struct {
9642 float x, y, z;
9643 float s, t;
9644 D3DCOLOR diffuse;
9645 } quad[] = {
9646 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9647 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9648 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9649 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9652 static const D3DVERTEXELEMENT9 decl_elements[] = {
9653 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9654 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9655 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9656 D3DDECL_END()
9659 static const struct {
9660 D3DTEXTUREOP op;
9661 const char *name;
9662 DWORD caps_flag;
9663 D3DCOLOR result;
9664 } test_data[] = {
9665 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9666 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9667 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9668 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9669 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9670 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9671 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9672 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9673 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9674 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9675 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9676 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9677 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9678 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9679 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9680 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9681 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9682 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9683 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9684 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9685 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9686 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9687 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9690 memset(&caps, 0, sizeof(caps));
9691 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9692 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9694 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9695 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9696 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9697 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9699 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9700 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9701 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9702 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9703 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9704 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9705 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9706 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9707 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9709 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9710 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9711 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9712 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9713 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9714 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9716 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9717 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9720 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9722 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9724 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9726 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9727 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9729 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9731 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9733 skip("tex operation %s not supported\n", test_data[i].name);
9734 continue;
9737 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9738 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9740 hr = IDirect3DDevice9_BeginScene(device);
9741 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9744 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9746 hr = IDirect3DDevice9_EndScene(device);
9747 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9749 color = getPixelColor(device, 320, 240);
9750 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9751 test_data[i].name, color, test_data[i].result);
9753 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9754 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9757 if (texture) IDirect3DTexture9_Release(texture);
9758 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9761 static void yuv_color_test(IDirect3DDevice9 *device) {
9762 HRESULT hr;
9763 IDirect3DSurface9 *surface = NULL, *target = NULL;
9764 unsigned int fmt, i;
9765 D3DFORMAT format;
9766 const char *fmt_string;
9767 D3DLOCKED_RECT lr;
9768 IDirect3D9 *d3d;
9769 HRESULT color;
9770 DWORD ref_color_left, ref_color_right;
9772 struct {
9773 DWORD in; /* The input color */
9774 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9775 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9776 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9777 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9778 } test_data[] = {
9779 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9780 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9781 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9782 * that
9784 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9785 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9786 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9787 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9788 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9789 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9790 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9791 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9792 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9793 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9794 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9795 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9796 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9797 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9799 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9800 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9801 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9802 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9805 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9806 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9807 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9808 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9810 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9811 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9813 for(fmt = 0; fmt < 2; fmt++) {
9814 if(fmt == 0) {
9815 format = D3DFMT_UYVY;
9816 fmt_string = "D3DFMT_UYVY";
9817 } else {
9818 format = D3DFMT_YUY2;
9819 fmt_string = "D3DFMT_YUY2";
9822 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9823 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9825 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9826 D3DRTYPE_SURFACE, format) != D3D_OK) {
9827 skip("%s is not supported\n", fmt_string);
9828 continue;
9831 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9832 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9833 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9835 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9836 if(fmt == 0) {
9837 ref_color_left = test_data[i].uyvy_left;
9838 ref_color_right = test_data[i].uyvy_right;
9839 } else {
9840 ref_color_left = test_data[i].yuy2_left;
9841 ref_color_right = test_data[i].yuy2_right;
9844 memset(&lr, 0, sizeof(lr));
9845 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9846 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9847 *((DWORD *) lr.pBits) = test_data[i].in;
9848 hr = IDirect3DSurface9_UnlockRect(surface);
9849 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9853 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9854 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9856 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9857 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9858 * want to add tests for the filtered pixels as well.
9860 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9861 * differently, so we need a max diff of 16
9863 color = getPixelColor(device, 40, 240);
9865 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9866 * where U != V. Skip the entire test if this bug in this case
9868 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9870 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9871 IDirect3DSurface9_Release(surface);
9872 goto out;
9875 ok(color_match(color, ref_color_left, 18),
9876 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9877 test_data[i].in, color, ref_color_left, fmt_string);
9878 color = getPixelColor(device, 600, 240);
9879 ok(color_match(color, ref_color_right, 18),
9880 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9881 test_data[i].in, color, ref_color_right, fmt_string);
9882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9883 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9885 IDirect3DSurface9_Release(surface);
9888 out:
9889 IDirect3DSurface9_Release(target);
9890 IDirect3D9_Release(d3d);
9893 static void texop_range_test(IDirect3DDevice9 *device)
9895 static const struct {
9896 float x, y, z;
9897 D3DCOLOR diffuse;
9898 } quad[] = {
9899 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9900 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9901 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9902 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9904 HRESULT hr;
9905 IDirect3DTexture9 *texture;
9906 D3DLOCKED_RECT locked_rect;
9907 D3DCAPS9 caps;
9908 DWORD color;
9910 /* We need ADD and SUBTRACT operations */
9911 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9912 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9913 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9914 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9915 return;
9917 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9918 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9919 return;
9922 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9923 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9924 /* Stage 1: result = diffuse(=1.0) + diffuse
9925 * stage 2: result = result - tfactor(= 0.5)
9927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9928 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9929 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9930 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9931 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9932 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9933 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9934 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9935 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9936 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9937 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9938 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9939 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9940 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9942 hr = IDirect3DDevice9_BeginScene(device);
9943 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9946 hr = IDirect3DDevice9_EndScene(device);
9947 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9949 color = getPixelColor(device, 320, 240);
9950 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9951 color);
9952 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9953 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9955 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9956 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9957 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9958 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9959 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9960 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9961 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9962 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9963 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9965 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9966 * stage 2: result = result + diffuse(1.0)
9968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9969 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9970 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9971 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9972 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9973 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9974 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9975 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9976 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9977 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9978 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9979 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9980 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9981 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9983 hr = IDirect3DDevice9_BeginScene(device);
9984 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9986 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9987 hr = IDirect3DDevice9_EndScene(device);
9988 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9990 color = getPixelColor(device, 320, 240);
9991 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9992 color);
9993 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9994 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9996 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9997 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9998 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9999 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10000 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10001 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10002 IDirect3DTexture9_Release(texture);
10005 static void alphareplicate_test(IDirect3DDevice9 *device) {
10006 struct vertex quad[] = {
10007 { -1.0, -1.0, 0.1, 0x80ff00ff },
10008 { 1.0, -1.0, 0.1, 0x80ff00ff },
10009 { -1.0, 1.0, 0.1, 0x80ff00ff },
10010 { 1.0, 1.0, 0.1, 0x80ff00ff },
10012 HRESULT hr;
10013 DWORD color;
10015 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10016 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10018 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10019 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10021 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10022 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10024 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10026 hr = IDirect3DDevice9_BeginScene(device);
10027 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10028 if(SUCCEEDED(hr)) {
10029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10030 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10031 hr = IDirect3DDevice9_EndScene(device);
10032 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10035 color = getPixelColor(device, 320, 240);
10036 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10037 color);
10038 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10039 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10041 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10042 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10046 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10047 HRESULT hr;
10048 D3DCAPS9 caps;
10049 DWORD color;
10050 struct vertex quad[] = {
10051 { -1.0, -1.0, 0.1, 0x408080c0 },
10052 { 1.0, -1.0, 0.1, 0x408080c0 },
10053 { -1.0, 1.0, 0.1, 0x408080c0 },
10054 { 1.0, 1.0, 0.1, 0x408080c0 },
10057 memset(&caps, 0, sizeof(caps));
10058 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10059 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10060 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10061 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10062 return;
10065 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10066 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10068 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10069 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10071 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10072 * mov r0.a, diffuse.a
10073 * mov r0, r0.a
10075 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10076 * 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
10077 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10079 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10080 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10081 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10082 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10083 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10084 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10085 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10086 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10087 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10088 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10089 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10090 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10091 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10092 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10093 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10094 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10095 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10096 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10098 hr = IDirect3DDevice9_BeginScene(device);
10099 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10100 if(SUCCEEDED(hr)) {
10101 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10102 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10103 hr = IDirect3DDevice9_EndScene(device);
10104 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10107 color = getPixelColor(device, 320, 240);
10108 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10109 color);
10110 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10111 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10113 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10114 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10115 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10117 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10118 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10121 static void zwriteenable_test(IDirect3DDevice9 *device) {
10122 HRESULT hr;
10123 DWORD color;
10124 struct vertex quad1[] = {
10125 { -1.0, -1.0, 0.1, 0x00ff0000},
10126 { -1.0, 1.0, 0.1, 0x00ff0000},
10127 { 1.0, -1.0, 0.1, 0x00ff0000},
10128 { 1.0, 1.0, 0.1, 0x00ff0000},
10130 struct vertex quad2[] = {
10131 { -1.0, -1.0, 0.9, 0x0000ff00},
10132 { -1.0, 1.0, 0.9, 0x0000ff00},
10133 { 1.0, -1.0, 0.9, 0x0000ff00},
10134 { 1.0, 1.0, 0.9, 0x0000ff00},
10137 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10138 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10140 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10141 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10147 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10149 hr = IDirect3DDevice9_BeginScene(device);
10150 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10151 if(SUCCEEDED(hr)) {
10152 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10153 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10154 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10155 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10156 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10157 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10160 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10162 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10164 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10166 hr = IDirect3DDevice9_EndScene(device);
10167 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10170 color = getPixelColor(device, 320, 240);
10171 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10172 color);
10173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10174 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10177 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10180 static void alphatest_test(IDirect3DDevice9 *device) {
10181 #define ALPHATEST_PASSED 0x0000ff00
10182 #define ALPHATEST_FAILED 0x00ff0000
10183 struct {
10184 D3DCMPFUNC func;
10185 DWORD color_less;
10186 DWORD color_equal;
10187 DWORD color_greater;
10188 } testdata[] = {
10189 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10190 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10191 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10192 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10193 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10194 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10195 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10196 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10198 unsigned int i, j;
10199 HRESULT hr;
10200 DWORD color;
10201 struct vertex quad[] = {
10202 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10203 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10204 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10205 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10207 D3DCAPS9 caps;
10209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10211 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10212 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10214 for(j = 0; j < 2; j++) {
10215 if(j == 1) {
10216 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10217 * the alpha test either for performance reasons(floating point RTs) or to work
10218 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10219 * codepath for ffp and shader in this case, and the test should cover both
10221 IDirect3DPixelShader9 *ps;
10222 DWORD shader_code[] = {
10223 0xffff0101, /* ps_1_1 */
10224 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10225 0x0000ffff /* end */
10227 memset(&caps, 0, sizeof(caps));
10228 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10229 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10230 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10231 break;
10234 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10235 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10236 IDirect3DDevice9_SetPixelShader(device, ps);
10237 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10238 IDirect3DPixelShader9_Release(ps);
10241 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10243 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10245 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10246 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10248 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10249 hr = IDirect3DDevice9_BeginScene(device);
10250 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10251 if(SUCCEEDED(hr)) {
10252 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10253 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10254 hr = IDirect3DDevice9_EndScene(device);
10255 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10257 color = getPixelColor(device, 320, 240);
10258 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10259 color, testdata[i].color_less, testdata[i].func);
10260 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10261 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10264 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10266 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10267 hr = IDirect3DDevice9_BeginScene(device);
10268 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10269 if(SUCCEEDED(hr)) {
10270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10271 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10272 hr = IDirect3DDevice9_EndScene(device);
10273 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10275 color = getPixelColor(device, 320, 240);
10276 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10277 color, testdata[i].color_equal, testdata[i].func);
10278 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10279 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10281 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10282 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10285 hr = IDirect3DDevice9_BeginScene(device);
10286 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10287 if(SUCCEEDED(hr)) {
10288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10289 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10290 hr = IDirect3DDevice9_EndScene(device);
10291 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10293 color = getPixelColor(device, 320, 240);
10294 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10295 color, testdata[i].color_greater, testdata[i].func);
10296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10297 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10303 IDirect3DDevice9_SetPixelShader(device, NULL);
10304 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10307 static void sincos_test(IDirect3DDevice9 *device) {
10308 const DWORD sin_shader_code[] = {
10309 0xfffe0200, /* vs_2_0 */
10310 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10311 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10312 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10313 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10314 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10315 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10316 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10317 0x0000ffff /* end */
10319 const DWORD cos_shader_code[] = {
10320 0xfffe0200, /* vs_2_0 */
10321 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10322 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10323 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10324 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10325 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10326 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10327 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10328 0x0000ffff /* end */
10330 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10331 HRESULT hr;
10332 struct {
10333 float x, y, z;
10334 } data[1280];
10335 unsigned int i;
10336 float sincosc1[4] = {D3DSINCOSCONST1};
10337 float sincosc2[4] = {D3DSINCOSCONST2};
10339 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10340 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10342 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10343 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10344 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10345 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10346 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10347 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10348 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10349 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10350 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10351 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10353 /* Generate a point from -1 to 1 every 0.5 pixels */
10354 for(i = 0; i < 1280; i++) {
10355 data[i].x = (-640.0 + i) / 640.0;
10356 data[i].y = 0.0;
10357 data[i].z = 0.1;
10360 hr = IDirect3DDevice9_BeginScene(device);
10361 if(SUCCEEDED(hr)) {
10362 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10363 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10365 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10367 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10368 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10370 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10372 hr = IDirect3DDevice9_EndScene(device);
10373 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10376 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10377 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10379 IDirect3DDevice9_SetVertexShader(device, NULL);
10380 IDirect3DVertexShader9_Release(sin_shader);
10381 IDirect3DVertexShader9_Release(cos_shader);
10384 static void loop_index_test(IDirect3DDevice9 *device) {
10385 const DWORD shader_code[] = {
10386 0xfffe0200, /* vs_2_0 */
10387 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10388 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10389 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10390 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10391 0x0000001d, /* endloop */
10392 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10393 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10394 0x0000ffff /* END */
10396 IDirect3DVertexShader9 *shader;
10397 HRESULT hr;
10398 DWORD color;
10399 const float quad[] = {
10400 -1.0, -1.0, 0.1,
10401 1.0, -1.0, 0.1,
10402 -1.0, 1.0, 0.1,
10403 1.0, 1.0, 0.1
10405 const float zero[4] = {0, 0, 0, 0};
10406 const float one[4] = {1, 1, 1, 1};
10407 int i0[4] = {2, 10, -3, 0};
10408 float values[4];
10410 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10411 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10412 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10413 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10414 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10415 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF 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 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10420 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10421 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10422 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10423 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10424 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10425 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10426 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10427 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10429 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10430 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10431 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10432 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10433 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10434 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10435 values[0] = 1.0;
10436 values[1] = 1.0;
10437 values[2] = 0.0;
10438 values[3] = 0.0;
10439 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10440 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10441 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10442 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10443 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10444 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10445 values[0] = -1.0;
10446 values[1] = 0.0;
10447 values[2] = 0.0;
10448 values[3] = 0.0;
10449 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10450 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10451 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10452 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10453 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10454 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10455 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10456 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10457 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10458 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10460 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10461 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10463 hr = IDirect3DDevice9_BeginScene(device);
10464 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10465 if(SUCCEEDED(hr))
10467 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10468 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10469 hr = IDirect3DDevice9_EndScene(device);
10470 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10472 color = getPixelColor(device, 320, 240);
10473 ok(color_match(color, 0x0000ff00, 1),
10474 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10476 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10478 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10479 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10480 IDirect3DVertexShader9_Release(shader);
10483 static void sgn_test(IDirect3DDevice9 *device) {
10484 const DWORD shader_code[] = {
10485 0xfffe0200, /* vs_2_0 */
10486 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10487 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10488 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10489 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10490 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10491 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10492 0x0000ffff /* end */
10494 IDirect3DVertexShader9 *shader;
10495 HRESULT hr;
10496 DWORD color;
10497 const float quad[] = {
10498 -1.0, -1.0, 0.1,
10499 1.0, -1.0, 0.1,
10500 -1.0, 1.0, 0.1,
10501 1.0, 1.0, 0.1
10504 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10505 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10506 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10507 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10508 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10509 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10511 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10513 hr = IDirect3DDevice9_BeginScene(device);
10514 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10515 if(SUCCEEDED(hr))
10517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10518 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10519 hr = IDirect3DDevice9_EndScene(device);
10520 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10522 color = getPixelColor(device, 320, 240);
10523 ok(color_match(color, 0x008000ff, 1),
10524 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10525 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10526 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10528 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10529 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10530 IDirect3DVertexShader9_Release(shader);
10533 static void viewport_test(IDirect3DDevice9 *device) {
10534 HRESULT hr;
10535 DWORD color;
10536 D3DVIEWPORT9 vp, old_vp;
10537 BOOL draw_failed = TRUE;
10538 const float quad[] =
10540 -0.5, -0.5, 0.1,
10541 0.5, -0.5, 0.1,
10542 -0.5, 0.5, 0.1,
10543 0.5, 0.5, 0.1
10546 memset(&old_vp, 0, sizeof(old_vp));
10547 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10548 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10550 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10551 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10553 /* Test a viewport with Width and Height bigger than the surface dimensions
10555 * TODO: Test Width < surface.width, but X + Width > surface.width
10556 * TODO: Test Width < surface.width, what happens with the height?
10558 * The expected behavior is that the viewport behaves like the "default"
10559 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10560 * MinZ = 0.0, MaxZ = 1.0.
10562 * Starting with Windows 7 the behavior among driver versions is not
10563 * consistent. The SetViewport call is accepted on all drivers. Some
10564 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10565 * nvidia drivers draw, but use the actual values in the viewport and only
10566 * display the upper left part on the surface.
10568 memset(&vp, 0, sizeof(vp));
10569 vp.X = 0;
10570 vp.Y = 0;
10571 vp.Width = 10000;
10572 vp.Height = 10000;
10573 vp.MinZ = 0.0;
10574 vp.MaxZ = 0.0;
10575 hr = IDirect3DDevice9_SetViewport(device, &vp);
10576 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10578 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10579 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10580 hr = IDirect3DDevice9_BeginScene(device);
10581 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10582 if(SUCCEEDED(hr))
10584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10585 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10586 draw_failed = FAILED(hr);
10587 hr = IDirect3DDevice9_EndScene(device);
10588 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10591 if(!draw_failed)
10593 color = getPixelColor(device, 158, 118);
10594 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10595 color = getPixelColor(device, 162, 118);
10596 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10597 color = getPixelColor(device, 158, 122);
10598 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10599 color = getPixelColor(device, 162, 122);
10600 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10602 color = getPixelColor(device, 478, 358);
10603 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10604 color = getPixelColor(device, 482, 358);
10605 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10606 color = getPixelColor(device, 478, 362);
10607 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10608 color = getPixelColor(device, 482, 362);
10609 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10612 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10613 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10615 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10616 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10619 /* This test tests depth clamping / clipping behaviour:
10620 * - With software vertex processing, depth values are clamped to the
10621 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10622 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10623 * same as regular vertices here.
10624 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10625 * Normal vertices are always clipped. Pretransformed vertices are
10626 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10627 * - The viewport's MinZ/MaxZ is irrelevant for this.
10629 static void depth_clamp_test(IDirect3DDevice9 *device)
10631 const struct tvertex quad1[] =
10633 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10634 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10635 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10636 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10638 const struct tvertex quad2[] =
10640 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10641 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10642 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10643 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10645 const struct tvertex quad3[] =
10647 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10648 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10649 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10650 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10652 const struct tvertex quad4[] =
10654 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10655 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10656 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10657 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10659 const struct vertex quad5[] =
10661 { -0.5f, 0.5f, 10.0f, 0xff14f914},
10662 { 0.5f, 0.5f, 10.0f, 0xff14f914},
10663 { -0.5f, -0.5f, 10.0f, 0xff14f914},
10664 { 0.5f, -0.5f, 10.0f, 0xff14f914},
10666 const struct vertex quad6[] =
10668 { -1.0f, 0.5f, 10.0f, 0xfff91414},
10669 { 1.0f, 0.5f, 10.0f, 0xfff91414},
10670 { -1.0f, 0.25f, 10.0f, 0xfff91414},
10671 { 1.0f, 0.25f, 10.0f, 0xfff91414},
10674 D3DVIEWPORT9 vp;
10675 D3DCOLOR color;
10676 D3DCAPS9 caps;
10677 HRESULT hr;
10679 vp.X = 0;
10680 vp.Y = 0;
10681 vp.Width = 640;
10682 vp.Height = 480;
10683 vp.MinZ = 0.0;
10684 vp.MaxZ = 7.5;
10686 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10687 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10689 hr = IDirect3DDevice9_SetViewport(device, &vp);
10690 if(FAILED(hr))
10692 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10693 * the tests because the 7.5 is just intended to show that it doesn't have
10694 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10695 * viewport and continue.
10697 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10698 vp.MaxZ = 1.0;
10699 hr = IDirect3DDevice9_SetViewport(device, &vp);
10701 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10704 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10707 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10709 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10711 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10713 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);
10723 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10724 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10726 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10727 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10730 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10732 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10735 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10738 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10741 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10744 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10747 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10749 hr = IDirect3DDevice9_EndScene(device);
10750 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10752 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10754 color = getPixelColor(device, 75, 75);
10755 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10756 color = getPixelColor(device, 150, 150);
10757 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10758 color = getPixelColor(device, 320, 240);
10759 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10760 color = getPixelColor(device, 320, 330);
10761 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10762 color = getPixelColor(device, 320, 330);
10763 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10765 else
10767 color = getPixelColor(device, 75, 75);
10768 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10769 color = getPixelColor(device, 150, 150);
10770 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10771 color = getPixelColor(device, 320, 240);
10772 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10773 color = getPixelColor(device, 320, 330);
10774 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10775 color = getPixelColor(device, 320, 330);
10776 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10779 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10780 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10782 vp.MinZ = 0.0;
10783 vp.MaxZ = 1.0;
10784 hr = IDirect3DDevice9_SetViewport(device, &vp);
10785 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10788 static void depth_bounds_test(IDirect3DDevice9 *device)
10790 const struct tvertex quad1[] =
10792 { 0, 0, 0.0f, 1, 0xfff9e814},
10793 { 640, 0, 0.0f, 1, 0xfff9e814},
10794 { 0, 480, 1.0f, 1, 0xfff9e814},
10795 { 640, 480, 1.0f, 1, 0xfff9e814},
10797 const struct tvertex quad2[] =
10799 { 0, 0, 0.6f, 1, 0xff002b7f},
10800 { 640, 0, 0.6f, 1, 0xff002b7f},
10801 { 0, 480, 0.6f, 1, 0xff002b7f},
10802 { 640, 480, 0.6f, 1, 0xff002b7f},
10804 const struct tvertex quad3[] =
10806 { 0, 100, 0.6f, 1, 0xfff91414},
10807 { 640, 100, 0.6f, 1, 0xfff91414},
10808 { 0, 160, 0.6f, 1, 0xfff91414},
10809 { 640, 160, 0.6f, 1, 0xfff91414},
10812 union {
10813 DWORD d;
10814 float f;
10815 } tmpvalue;
10817 IDirect3D9 *d3d = NULL;
10818 IDirect3DSurface9 *offscreen_surface = NULL;
10819 D3DCOLOR color;
10820 HRESULT hr;
10822 IDirect3DDevice9_GetDirect3D(device, &d3d);
10823 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10824 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10825 skip("No NVDB (depth bounds test) support\n");
10826 IDirect3D9_Release(d3d);
10827 return;
10829 IDirect3D9_Release(d3d);
10831 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10832 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10833 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10834 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10836 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10837 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10840 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10842 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10844 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10846 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10849 hr = IDirect3DDevice9_BeginScene(device);
10850 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10853 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10855 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10856 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10859 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10861 tmpvalue.f = 0.625;
10862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10863 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10865 tmpvalue.f = 0.75;
10866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10867 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10870 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10872 tmpvalue.f = 0.75;
10873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10874 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10877 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10880 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10882 hr = IDirect3DDevice9_EndScene(device);
10883 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10885 color = getPixelColor(device, 150, 130);
10886 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10887 color = getPixelColor(device, 150, 200);
10888 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10889 color = getPixelColor(device, 150, 300-5);
10890 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10891 color = getPixelColor(device, 150, 300+5);
10892 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10893 color = getPixelColor(device, 150, 330);
10894 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10895 color = getPixelColor(device, 150, 360-5);
10896 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10897 color = getPixelColor(device, 150, 360+5);
10898 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10900 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10901 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10904 static void depth_buffer_test(IDirect3DDevice9 *device)
10906 static const struct vertex quad1[] =
10908 { -1.0, 1.0, 0.33f, 0xff00ff00},
10909 { 1.0, 1.0, 0.33f, 0xff00ff00},
10910 { -1.0, -1.0, 0.33f, 0xff00ff00},
10911 { 1.0, -1.0, 0.33f, 0xff00ff00},
10913 static const struct vertex quad2[] =
10915 { -1.0, 1.0, 0.50f, 0xffff00ff},
10916 { 1.0, 1.0, 0.50f, 0xffff00ff},
10917 { -1.0, -1.0, 0.50f, 0xffff00ff},
10918 { 1.0, -1.0, 0.50f, 0xffff00ff},
10920 static const struct vertex quad3[] =
10922 { -1.0, 1.0, 0.66f, 0xffff0000},
10923 { 1.0, 1.0, 0.66f, 0xffff0000},
10924 { -1.0, -1.0, 0.66f, 0xffff0000},
10925 { 1.0, -1.0, 0.66f, 0xffff0000},
10927 static const DWORD expected_colors[4][4] =
10929 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10930 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10931 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10932 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10935 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10936 unsigned int i, j;
10937 D3DVIEWPORT9 vp;
10938 D3DCOLOR color;
10939 HRESULT hr;
10941 vp.X = 0;
10942 vp.Y = 0;
10943 vp.Width = 640;
10944 vp.Height = 480;
10945 vp.MinZ = 0.0;
10946 vp.MaxZ = 1.0;
10948 hr = IDirect3DDevice9_SetViewport(device, &vp);
10949 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10952 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10953 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10954 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10956 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10958 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10960 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10962 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10963 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10964 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10965 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10966 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10967 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10968 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10969 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10970 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10971 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10972 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10974 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10975 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10976 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10977 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10979 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10980 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10982 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10984 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10985 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10986 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10987 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10989 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10990 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10991 hr = IDirect3DDevice9_BeginScene(device);
10992 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10994 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10995 hr = IDirect3DDevice9_EndScene(device);
10996 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10998 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10999 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11000 IDirect3DSurface9_Release(backbuffer);
11001 IDirect3DSurface9_Release(rt3);
11002 IDirect3DSurface9_Release(rt2);
11003 IDirect3DSurface9_Release(rt1);
11005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11006 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11008 hr = IDirect3DDevice9_BeginScene(device);
11009 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11010 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11011 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11012 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11013 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11014 hr = IDirect3DDevice9_EndScene(device);
11015 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11017 for (i = 0; i < 4; ++i)
11019 for (j = 0; j < 4; ++j)
11021 unsigned int x = 80 * ((2 * j) + 1);
11022 unsigned int y = 60 * ((2 * i) + 1);
11023 color = getPixelColor(device, x, y);
11024 ok(color_match(color, expected_colors[i][j], 0),
11025 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11029 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11030 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11033 /* Test that partial depth copies work the way they're supposed to. The clear
11034 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11035 * the following draw should only copy back the part that was modified. */
11036 static void depth_buffer2_test(IDirect3DDevice9 *device)
11038 static const struct vertex quad[] =
11040 { -1.0, 1.0, 0.66f, 0xffff0000},
11041 { 1.0, 1.0, 0.66f, 0xffff0000},
11042 { -1.0, -1.0, 0.66f, 0xffff0000},
11043 { 1.0, -1.0, 0.66f, 0xffff0000},
11046 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11047 unsigned int i, j;
11048 D3DVIEWPORT9 vp;
11049 D3DCOLOR color;
11050 HRESULT hr;
11052 vp.X = 0;
11053 vp.Y = 0;
11054 vp.Width = 640;
11055 vp.Height = 480;
11056 vp.MinZ = 0.0;
11057 vp.MaxZ = 1.0;
11059 hr = IDirect3DDevice9_SetViewport(device, &vp);
11060 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11063 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11065 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11067 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11069 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11070 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11071 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11073 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11074 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11075 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11076 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11077 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11078 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11079 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11080 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11082 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11083 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11084 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11085 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11087 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11088 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11090 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11092 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11093 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11094 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11095 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11097 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11098 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11099 IDirect3DSurface9_Release(backbuffer);
11100 IDirect3DSurface9_Release(rt2);
11101 IDirect3DSurface9_Release(rt1);
11103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11104 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11106 hr = IDirect3DDevice9_BeginScene(device);
11107 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11109 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11110 hr = IDirect3DDevice9_EndScene(device);
11111 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11113 for (i = 0; i < 4; ++i)
11115 for (j = 0; j < 4; ++j)
11117 unsigned int x = 80 * ((2 * j) + 1);
11118 unsigned int y = 60 * ((2 * i) + 1);
11119 color = getPixelColor(device, x, y);
11120 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11121 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11125 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11126 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11129 static void depth_blit_test(IDirect3DDevice9 *device)
11131 static const struct vertex quad1[] =
11133 { -1.0, 1.0, 0.50f, 0xff00ff00},
11134 { 1.0, 1.0, 0.50f, 0xff00ff00},
11135 { -1.0, -1.0, 0.50f, 0xff00ff00},
11136 { 1.0, -1.0, 0.50f, 0xff00ff00},
11138 static const struct vertex quad2[] =
11140 { -1.0, 1.0, 0.66f, 0xff0000ff},
11141 { 1.0, 1.0, 0.66f, 0xff0000ff},
11142 { -1.0, -1.0, 0.66f, 0xff0000ff},
11143 { 1.0, -1.0, 0.66f, 0xff0000ff},
11145 static const DWORD expected_colors[4][4] =
11147 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11148 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11149 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11150 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11153 IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11154 RECT src_rect, dst_rect;
11155 unsigned int i, j;
11156 D3DVIEWPORT9 vp;
11157 D3DCOLOR color;
11158 HRESULT hr;
11160 vp.X = 0;
11161 vp.Y = 0;
11162 vp.Width = 640;
11163 vp.Height = 480;
11164 vp.MinZ = 0.0;
11165 vp.MaxZ = 1.0;
11167 hr = IDirect3DDevice9_SetViewport(device, &vp);
11168 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11170 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11171 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11172 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11173 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11174 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11175 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11176 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11177 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11180 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11182 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11183 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11184 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11185 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11186 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11189 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11190 SetRect(&dst_rect, 0, 0, 480, 360);
11191 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11192 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11193 SetRect(&dst_rect, 0, 0, 320, 240);
11194 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11195 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11197 /* Partial blit. */
11198 SetRect(&src_rect, 0, 0, 320, 240);
11199 SetRect(&dst_rect, 0, 0, 320, 240);
11200 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11201 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11202 /* Flipped. */
11203 SetRect(&src_rect, 0, 0, 640, 480);
11204 SetRect(&dst_rect, 0, 480, 640, 0);
11205 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11206 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11207 /* Full, explicit. */
11208 SetRect(&src_rect, 0, 0, 640, 480);
11209 SetRect(&dst_rect, 0, 0, 640, 480);
11210 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11211 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11212 /* Filtered blit. */
11213 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11214 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11215 /* Depth -> color blit.*/
11216 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11217 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11218 IDirect3DSurface9_Release(backbuffer);
11220 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11221 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11222 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11223 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11225 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11226 IDirect3DSurface9_Release(ds2);
11227 IDirect3DSurface9_Release(ds1);
11229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11230 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11231 hr = IDirect3DDevice9_BeginScene(device);
11232 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11234 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11236 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11237 hr = IDirect3DDevice9_EndScene(device);
11238 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11240 for (i = 0; i < 4; ++i)
11242 for (j = 0; j < 4; ++j)
11244 unsigned int x = 80 * ((2 * j) + 1);
11245 unsigned int y = 60 * ((2 * i) + 1);
11246 color = getPixelColor(device, x, y);
11247 ok(color_match(color, expected_colors[i][j], 0),
11248 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11252 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11253 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11256 static void intz_test(IDirect3DDevice9 *device)
11258 static const DWORD ps_code[] =
11260 0xffff0200, /* ps_2_0 */
11261 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11262 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11263 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11264 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11265 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11266 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11267 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11268 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11269 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11270 0x0000ffff, /* end */
11272 struct
11274 float x, y, z;
11275 float s, t, p, q;
11277 quad[] =
11279 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11280 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11281 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11282 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11284 struct
11286 UINT x, y;
11287 D3DCOLOR color;
11289 expected_colors[] =
11291 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11292 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11293 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11294 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11295 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11296 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11297 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11298 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11301 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11302 IDirect3DTexture9 *texture;
11303 IDirect3DPixelShader9 *ps;
11304 IDirect3DSurface9 *ds;
11305 IDirect3D9 *d3d9;
11306 D3DCAPS9 caps;
11307 HRESULT hr;
11308 UINT i;
11310 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11311 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11312 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11314 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11315 return;
11318 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11319 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11321 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11322 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11323 if (FAILED(hr))
11325 skip("No INTZ support, skipping INTZ test.\n");
11326 return;
11329 IDirect3D9_Release(d3d9);
11331 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11332 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11333 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11334 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11336 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11337 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11338 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11339 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11340 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11341 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11342 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11343 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11345 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11346 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11348 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11350 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11351 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11352 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11354 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11356 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11357 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11358 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11359 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11360 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11361 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11362 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11363 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11364 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11365 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11367 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11368 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11369 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11370 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11371 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11372 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11373 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11374 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11376 /* Setup the depth/stencil surface. */
11377 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11378 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11380 hr = IDirect3DDevice9_BeginScene(device);
11381 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11383 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11384 hr = IDirect3DDevice9_EndScene(device);
11385 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11387 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11388 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11389 IDirect3DSurface9_Release(ds);
11390 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11391 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11392 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11393 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11394 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11395 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11397 /* Read the depth values back. */
11398 hr = IDirect3DDevice9_BeginScene(device);
11399 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11401 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11402 hr = IDirect3DDevice9_EndScene(device);
11403 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11405 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11407 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11408 ok(color_match(color, expected_colors[i].color, 1),
11409 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11410 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11413 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11414 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11416 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11417 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11418 IDirect3DSurface9_Release(original_ds);
11419 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11420 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11421 IDirect3DTexture9_Release(texture);
11422 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11423 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11424 IDirect3DPixelShader9_Release(ps);
11426 IDirect3DSurface9_Release(original_rt);
11427 IDirect3DSurface9_Release(rt);
11430 static void shadow_test(IDirect3DDevice9 *device)
11432 static const DWORD ps_code[] =
11434 0xffff0200, /* ps_2_0 */
11435 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11436 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11437 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11438 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11439 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11440 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11441 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11442 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11443 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11444 0x0000ffff, /* end */
11446 struct
11448 D3DFORMAT format;
11449 const char *name;
11451 formats[] =
11453 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11454 {D3DFMT_D32, "D3DFMT_D32"},
11455 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11456 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11457 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11458 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11459 {D3DFMT_D16, "D3DFMT_D16"},
11460 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11461 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11463 struct
11465 float x, y, z;
11466 float s, t, p, q;
11468 quad[] =
11470 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11471 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11472 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11473 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11475 struct
11477 UINT x, y;
11478 D3DCOLOR color;
11480 expected_colors[] =
11482 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11483 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11484 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11485 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11486 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11487 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11488 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11489 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11492 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11493 IDirect3DPixelShader9 *ps;
11494 IDirect3D9 *d3d9;
11495 D3DCAPS9 caps;
11496 HRESULT hr;
11497 UINT i;
11499 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11500 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11501 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11503 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11504 return;
11507 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11508 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11509 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11510 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11511 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11512 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11514 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11515 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11516 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11517 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11518 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11520 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11521 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11523 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11525 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11527 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11529 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11531 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11532 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11533 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11534 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11535 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11536 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11537 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11538 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11539 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11540 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11542 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11544 D3DFORMAT format = formats[i].format;
11545 IDirect3DTexture9 *texture;
11546 IDirect3DSurface9 *ds;
11547 unsigned int j;
11549 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11550 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11551 if (FAILED(hr)) continue;
11553 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11554 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11555 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11557 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11558 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11560 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11561 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11563 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11564 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11566 IDirect3DDevice9_SetPixelShader(device, NULL);
11567 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11569 /* Setup the depth/stencil surface. */
11570 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11571 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11573 hr = IDirect3DDevice9_BeginScene(device);
11574 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11576 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11577 hr = IDirect3DDevice9_EndScene(device);
11578 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11580 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11581 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11582 IDirect3DSurface9_Release(ds);
11584 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11585 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11587 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11588 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11590 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11591 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11593 /* Do the actual shadow mapping. */
11594 hr = IDirect3DDevice9_BeginScene(device);
11595 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11597 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11598 hr = IDirect3DDevice9_EndScene(device);
11599 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11601 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11602 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11603 IDirect3DTexture9_Release(texture);
11605 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11607 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11608 ok(color_match(color, expected_colors[j].color, 0),
11609 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11610 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11611 formats[i].name, color);
11614 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11615 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11618 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11619 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11620 IDirect3DPixelShader9_Release(ps);
11622 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11623 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11624 IDirect3DSurface9_Release(original_ds);
11626 IDirect3DSurface9_Release(original_rt);
11627 IDirect3DSurface9_Release(rt);
11629 IDirect3D9_Release(d3d9);
11632 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11634 const struct vertex quad1[] =
11636 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11637 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11638 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
11639 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
11641 const struct vertex quad2[] =
11643 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11644 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11645 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
11646 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
11648 D3DCOLOR color;
11649 HRESULT hr;
11651 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11652 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11654 hr = IDirect3DDevice9_BeginScene(device);
11655 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11657 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11658 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11661 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11663 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11666 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11667 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11668 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11670 hr = IDirect3DDevice9_EndScene(device);
11671 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11673 color = getPixelColor(device, 1, 240);
11674 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11675 color = getPixelColor(device, 638, 240);
11676 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11678 color = getPixelColor(device, 1, 241);
11679 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11680 color = getPixelColor(device, 638, 241);
11681 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11684 static void clip_planes_test(IDirect3DDevice9 *device)
11686 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11688 const DWORD shader_code[] = {
11689 0xfffe0200, /* vs_2_0 */
11690 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11691 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11692 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11693 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11694 0x0000ffff /* end */
11696 IDirect3DVertexShader9 *shader;
11698 IDirect3DTexture9 *offscreen = NULL;
11699 IDirect3DSurface9 *offscreen_surface, *original_rt;
11700 HRESULT hr;
11702 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11703 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11706 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11708 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11710 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11712 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11714 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11715 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11716 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11719 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11721 clip_planes(device, "Onscreen FFP");
11723 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11724 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11725 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11726 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11727 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11728 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11730 clip_planes(device, "Offscreen FFP");
11732 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11733 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11735 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11736 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11737 IDirect3DDevice9_SetVertexShader(device, shader);
11738 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11740 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11741 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11743 clip_planes(device, "Onscreen vertex shader");
11745 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11746 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11748 clip_planes(device, "Offscreen vertex shader");
11750 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11751 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11753 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11754 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11755 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11756 IDirect3DVertexShader9_Release(shader);
11757 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11758 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11759 IDirect3DSurface9_Release(original_rt);
11760 IDirect3DSurface9_Release(offscreen_surface);
11761 IDirect3DTexture9_Release(offscreen);
11764 static void fp_special_test(IDirect3DDevice9 *device)
11766 static const DWORD vs_header[] =
11768 0xfffe0200, /* vs_2_0 */
11769 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11770 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11771 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11774 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11775 static const DWORD vs_pow[] =
11776 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11777 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11778 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11779 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11780 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11781 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11783 static const DWORD vs_footer[] =
11785 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11786 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11787 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11788 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11789 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11790 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11791 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11792 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11793 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11794 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11795 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11796 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11797 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11798 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11799 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11800 0x0000ffff, /* end */
11803 static const struct
11805 const char *name;
11806 const DWORD *ops;
11807 DWORD size;
11808 D3DCOLOR r600;
11809 D3DCOLOR nv40;
11810 D3DCOLOR nv50;
11812 vs_body[] =
11814 /* The basic ideas here are:
11815 * 2.0 * +/-INF == +/-INF
11816 * NAN != NAN
11818 * The vertex shader value is written to the red component, with 0.0
11819 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11820 * result in 0x00. The pixel shader value is written to the green
11821 * component, but here 0.0 also results in 0x00. The actual value is
11822 * written to the blue component.
11824 * There are considerable differences between graphics cards in how
11825 * these are handled, but pow and nrm never generate INF or NAN. */
11826 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
11827 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
11828 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
11829 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11830 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
11831 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11832 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11835 static const DWORD ps_code[] =
11837 0xffff0200, /* ps_2_0 */
11838 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11839 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11840 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11841 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11842 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11843 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11844 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11845 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11846 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11847 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11848 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11849 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11850 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11851 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11852 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11853 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11854 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11855 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11856 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11857 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11858 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11859 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11860 0x0000ffff, /* end */
11863 struct
11865 float x, y, z;
11866 float s;
11868 quad[] =
11870 { -1.0f, 1.0f, 0.0f, 0.0f},
11871 { 1.0f, 1.0f, 1.0f, 0.0f},
11872 { -1.0f, -1.0f, 0.0f, 0.0f},
11873 { 1.0f, -1.0f, 1.0f, 0.0f},
11876 IDirect3DPixelShader9 *ps;
11877 UINT body_size = 0;
11878 DWORD *vs_code;
11879 D3DCAPS9 caps;
11880 HRESULT hr;
11881 UINT i;
11883 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11884 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11885 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11887 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11888 return;
11891 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11892 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11894 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11895 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11896 IDirect3DDevice9_SetPixelShader(device, ps);
11897 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11899 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11900 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11902 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11903 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11905 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11907 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11910 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11911 memcpy(vs_code, vs_header, sizeof(vs_header));
11913 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11915 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11916 IDirect3DVertexShader9 *vs;
11917 D3DCOLOR color;
11919 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11920 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11921 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11923 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11924 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11925 IDirect3DDevice9_SetVertexShader(device, vs);
11926 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11928 hr = IDirect3DDevice9_BeginScene(device);
11929 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11931 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11932 hr = IDirect3DDevice9_EndScene(device);
11933 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11935 color = getPixelColor(device, 320, 240);
11936 ok(color_match(color, vs_body[i].r600, 1)
11937 || color_match(color, vs_body[i].nv40, 1)
11938 || color_match(color, vs_body[i].nv50, 1),
11939 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11940 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11942 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11943 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11945 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11946 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11947 IDirect3DVertexShader9_Release(vs);
11950 HeapFree(GetProcessHeap(), 0, vs_code);
11952 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11953 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11954 IDirect3DPixelShader9_Release(ps);
11957 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11959 IDirect3D9 *d3d;
11960 IDirect3DSurface9 *rt, *backbuffer;
11961 IDirect3DTexture9 *texture;
11962 HRESULT hr;
11963 int i;
11964 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11965 static const struct
11967 D3DFORMAT fmt;
11968 const char *name;
11970 formats[] =
11972 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11973 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11974 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11975 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11976 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11978 static const struct
11980 float x, y, z;
11981 float u, v;
11983 quad[] =
11985 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
11986 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
11987 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
11988 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
11991 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11992 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11993 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11994 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11995 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11996 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11997 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11998 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12000 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12002 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12004 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12005 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12007 skip("Format %s not supported as render target, skipping test.\n",
12008 formats[i].name);
12009 continue;
12012 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12013 D3DPOOL_DEFAULT, &texture, NULL);
12014 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12015 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12016 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12018 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12019 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12020 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12021 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12022 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12023 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12025 hr = IDirect3DDevice9_BeginScene(device);
12026 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12027 if(SUCCEEDED(hr))
12029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12030 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12031 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12032 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12034 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12036 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12037 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12038 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12039 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12040 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12041 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12042 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12043 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12045 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12046 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12047 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12049 hr = IDirect3DDevice9_EndScene(device);
12050 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12053 IDirect3DSurface9_Release(rt);
12054 IDirect3DTexture9_Release(texture);
12056 color = getPixelColor(device, 360, 240);
12057 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12058 D3DUSAGE_QUERY_SRGBWRITE,
12059 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12061 /* Big slop for R5G6B5 */
12062 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12063 formats[i].name, color_srgb, color);
12065 else
12067 /* Big slop for R5G6B5 */
12068 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12069 formats[i].name, color_rgb, color);
12072 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12073 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12076 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12077 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12079 IDirect3D9_Release(d3d);
12080 IDirect3DSurface9_Release(backbuffer);
12083 static void ds_size_test(IDirect3DDevice9 *device)
12085 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12086 HRESULT hr;
12087 DWORD color;
12088 DWORD num_passes;
12089 struct
12091 float x, y, z;
12093 quad[] =
12095 {-1.0, -1.0, 0.0 },
12096 {-1.0, 1.0, 0.0 },
12097 { 1.0, -1.0, 0.0 },
12098 { 1.0, 1.0, 0.0 }
12101 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12102 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12103 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12104 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12105 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12106 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12109 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12111 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12114 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12115 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12116 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12117 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12118 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12119 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12120 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12121 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12122 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12123 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12124 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12125 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12127 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12128 * but does not change the surface's contents. */
12129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12130 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12132 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12134 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12136 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12137 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
12138 color = getPixelColorFromSurface(readback, 2, 2);
12139 ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
12140 color = getPixelColorFromSurface(readback, 31, 31);
12141 ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
12142 color = getPixelColorFromSurface(readback, 32, 32);
12143 ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
12144 color = getPixelColorFromSurface(readback, 63, 63);
12145 ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
12147 /* Turning on any depth-related state results in a ValidateDevice failure */
12148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12149 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12150 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12151 ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12152 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12154 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12155 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12156 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12157 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12158 ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12159 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12161 /* Try to draw with the device in an invalid state */
12162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12163 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12164 hr = IDirect3DDevice9_BeginScene(device);
12165 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12166 if(SUCCEEDED(hr))
12168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12169 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12170 hr = IDirect3DDevice9_EndScene(device);
12171 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12174 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12175 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12176 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12177 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12178 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12179 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12181 IDirect3DSurface9_Release(readback);
12182 IDirect3DSurface9_Release(ds);
12183 IDirect3DSurface9_Release(rt);
12184 IDirect3DSurface9_Release(old_rt);
12185 IDirect3DSurface9_Release(old_ds);
12188 static void unbound_sampler_test(IDirect3DDevice9 *device)
12190 HRESULT hr;
12191 IDirect3DPixelShader9 *ps;
12192 IDirect3DSurface9 *rt, *old_rt;
12193 DWORD color;
12195 static const DWORD ps_code[] =
12197 0xffff0200, /* ps_2_0 */
12198 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12199 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12200 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12201 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12202 0x0000ffff, /* end */
12205 static const struct
12207 float x, y, z;
12208 float u, v;
12210 quad[] =
12212 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12213 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12214 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12215 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12218 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12219 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12221 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12222 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12224 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12225 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12227 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12228 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12230 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12231 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12233 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12234 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12237 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12239 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12240 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12242 hr = IDirect3DDevice9_BeginScene(device);
12243 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12244 if(SUCCEEDED(hr))
12246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12247 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12249 hr = IDirect3DDevice9_EndScene(device);
12250 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12253 color = getPixelColorFromSurface(rt, 32, 32);
12254 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12256 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12259 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12260 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12262 IDirect3DSurface9_Release(rt);
12263 IDirect3DSurface9_Release(old_rt);
12264 IDirect3DPixelShader9_Release(ps);
12267 static void update_surface_test(IDirect3DDevice9 *device)
12269 static const BYTE blocks[][8] =
12271 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12272 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12273 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12274 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12275 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12276 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12277 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12279 static const struct
12281 UINT x, y;
12282 D3DCOLOR color;
12284 expected_colors[] =
12286 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12287 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12288 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12289 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12290 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12291 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12292 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12294 static const struct
12296 float x, y, z, w;
12297 float u, v;
12299 tri[] =
12301 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12302 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12303 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12305 static const RECT rect_2x2 = {0, 0, 2, 2};
12306 static const struct
12308 UINT src_level;
12309 UINT dst_level;
12310 const RECT *r;
12311 HRESULT hr;
12313 block_size_tests[] =
12315 {1, 0, NULL, D3D_OK},
12316 {0, 1, NULL, D3DERR_INVALIDCALL},
12317 {5, 4, NULL, D3DERR_INVALIDCALL},
12318 {4, 5, NULL, D3DERR_INVALIDCALL},
12319 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12320 {5, 5, &rect_2x2, D3D_OK},
12323 IDirect3DSurface9 *src_surface, *dst_surface;
12324 IDirect3DTexture9 *src_tex, *dst_tex;
12325 IDirect3D9 *d3d;
12326 UINT count, i;
12327 HRESULT hr;
12329 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12330 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12332 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12333 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12334 IDirect3D9_Release(d3d);
12335 if (FAILED(hr))
12337 skip("DXT1 not supported, skipping test.\n");
12338 return;
12341 IDirect3D9_Release(d3d);
12343 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12344 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12345 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12346 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12348 count = IDirect3DTexture9_GetLevelCount(src_tex);
12349 ok(count == 7, "Got level count %u, expected 7.\n", count);
12351 for (i = 0; i < count; ++i)
12353 UINT row_count, block_count, x, y;
12354 D3DSURFACE_DESC desc;
12355 BYTE *row, *block;
12356 D3DLOCKED_RECT r;
12358 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12359 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12361 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12362 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12364 row_count = ((desc.Height + 3) & ~3) / 4;
12365 block_count = ((desc.Width + 3) & ~3) / 4;
12366 row = r.pBits;
12368 for (y = 0; y < row_count; ++y)
12370 block = row;
12371 for (x = 0; x < block_count; ++x)
12373 memcpy(block, blocks[i], sizeof(blocks[i]));
12374 block += sizeof(blocks[i]);
12376 row += r.Pitch;
12379 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12380 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12383 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12385 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12386 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12387 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12388 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12390 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12391 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12392 hr, i, block_size_tests[i].hr);
12394 IDirect3DSurface9_Release(dst_surface);
12395 IDirect3DSurface9_Release(src_surface);
12398 for (i = 0; i < count; ++i)
12400 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12401 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12402 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12403 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12405 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12406 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12408 IDirect3DSurface9_Release(dst_surface);
12409 IDirect3DSurface9_Release(src_surface);
12412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12413 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12414 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12415 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12416 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12417 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12418 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12419 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12421 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12422 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12423 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12425 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12426 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12428 hr = IDirect3DDevice9_BeginScene(device);
12429 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12431 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12432 hr = IDirect3DDevice9_EndScene(device);
12433 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12435 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12437 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12438 ok(color_match(color, expected_colors[i].color, 0),
12439 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12440 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12443 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12444 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12446 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12447 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12448 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12449 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12450 IDirect3DTexture9_Release(dst_tex);
12451 IDirect3DTexture9_Release(src_tex);
12454 START_TEST(visual)
12456 IDirect3DDevice9 *device_ptr;
12457 D3DCAPS9 caps;
12458 HRESULT hr;
12459 DWORD color;
12461 d3d9_handle = LoadLibraryA("d3d9.dll");
12462 if (!d3d9_handle)
12464 skip("Could not load d3d9.dll\n");
12465 return;
12468 device_ptr = init_d3d9();
12469 if (!device_ptr)
12471 skip("Creating the device failed\n");
12472 return;
12475 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12477 /* Check for the reliability of the returned data */
12478 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12479 if(FAILED(hr))
12481 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12482 goto cleanup;
12485 color = getPixelColor(device_ptr, 1, 1);
12486 if(color !=0x00ff0000)
12488 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12489 goto cleanup;
12491 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12493 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12494 if(FAILED(hr))
12496 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12497 goto cleanup;
12500 color = getPixelColor(device_ptr, 639, 479);
12501 if(color != 0x0000ddee)
12503 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12504 goto cleanup;
12506 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12508 /* Now execute the real tests */
12509 depth_clamp_test(device_ptr);
12510 stretchrect_test(device_ptr);
12511 lighting_test(device_ptr);
12512 clear_test(device_ptr);
12513 color_fill_test(device_ptr);
12514 fog_test(device_ptr);
12515 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12517 test_cube_wrap(device_ptr);
12518 } else {
12519 skip("No cube texture support\n");
12521 z_range_test(device_ptr);
12522 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12524 maxmip_test(device_ptr);
12526 else
12528 skip("No mipmap support\n");
12530 offscreen_test(device_ptr);
12531 ds_size_test(device_ptr);
12532 alpha_test(device_ptr);
12533 shademode_test(device_ptr);
12534 srgbtexture_test(device_ptr);
12535 release_buffer_test(device_ptr);
12536 float_texture_test(device_ptr);
12537 g16r16_texture_test(device_ptr);
12538 pixelshader_blending_test(device_ptr);
12539 texture_transform_flags_test(device_ptr);
12540 autogen_mipmap_test(device_ptr);
12541 fixed_function_decl_test(device_ptr);
12542 conditional_np2_repeat_test(device_ptr);
12543 fixed_function_bumpmap_test(device_ptr);
12544 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12545 stencil_cull_test(device_ptr);
12546 } else {
12547 skip("No two sided stencil support\n");
12549 pointsize_test(device_ptr);
12550 tssargtemp_test(device_ptr);
12551 np2_stretch_rect_test(device_ptr);
12552 yuv_color_test(device_ptr);
12553 zwriteenable_test(device_ptr);
12554 alphatest_test(device_ptr);
12555 viewport_test(device_ptr);
12557 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12559 test_constant_clamp_vs(device_ptr);
12560 test_compare_instructions(device_ptr);
12562 else skip("No vs_1_1 support\n");
12564 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12566 test_mova(device_ptr);
12567 loop_index_test(device_ptr);
12568 sincos_test(device_ptr);
12569 sgn_test(device_ptr);
12570 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12571 test_vshader_input(device_ptr);
12572 test_vshader_float16(device_ptr);
12573 stream_test(device_ptr);
12574 } else {
12575 skip("No vs_3_0 support\n");
12578 else skip("No vs_2_0 support\n");
12580 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12582 fog_with_shader_test(device_ptr);
12584 else skip("No vs_1_1 and ps_1_1 support\n");
12586 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12588 texbem_test(device_ptr);
12589 texdepth_test(device_ptr);
12590 texkill_test(device_ptr);
12591 x8l8v8u8_test(device_ptr);
12592 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12593 constant_clamp_ps_test(device_ptr);
12594 cnd_test(device_ptr);
12595 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12596 dp2add_ps_test(device_ptr);
12597 unbound_sampler_test(device_ptr);
12598 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12599 nested_loop_test(device_ptr);
12600 pretransformed_varying_test(device_ptr);
12601 vFace_register_test(device_ptr);
12602 vpos_register_test(device_ptr);
12603 multiple_rendertargets_test(device_ptr);
12604 } else {
12605 skip("No ps_3_0 or vs_3_0 support\n");
12607 } else {
12608 skip("No ps_2_0 support\n");
12612 else skip("No ps_1_1 support\n");
12614 texop_test(device_ptr);
12615 texop_range_test(device_ptr);
12616 alphareplicate_test(device_ptr);
12617 dp3_alpha_test(device_ptr);
12618 depth_buffer_test(device_ptr);
12619 depth_buffer2_test(device_ptr);
12620 depth_blit_test(device_ptr);
12621 intz_test(device_ptr);
12622 shadow_test(device_ptr);
12623 fp_special_test(device_ptr);
12624 depth_bounds_test(device_ptr);
12625 srgbwrite_format_test(device_ptr);
12626 clip_planes_test(device_ptr);
12627 update_surface_test(device_ptr);
12629 cleanup:
12630 if(device_ptr) {
12631 D3DPRESENT_PARAMETERS present_parameters;
12632 IDirect3DSwapChain9 *swapchain;
12633 ULONG ref;
12635 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12636 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12637 IDirect3DSwapChain9_Release(swapchain);
12638 ref = IDirect3DDevice9_Release(device_ptr);
12639 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12640 DestroyWindow(present_parameters.hDeviceWindow);