quartz: Free two assert calls from having side effects.
[wine/testsucceed.git] / dlls / d3d9 / tests / visual.c
blob972f8d66c549b46f12e9a32c7b1a4b07dbab974a
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, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1235 "Unfogged quad has color %08x\n", color);
1236 color = getPixelColor(device, 160, 120);
1237 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1238 "Fogged out quad has color %08x\n", color);
1240 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1242 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1243 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1244 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1245 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1246 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1249 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1251 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1253 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1254 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1256 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1257 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1258 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1260 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1261 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1262 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1264 hr = IDirect3DDevice9_EndScene(device);
1265 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1267 else
1269 ok(FALSE, "BeginScene failed\n");
1272 color = getPixelColor(device, 160, 360);
1273 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1274 color = getPixelColor(device, 160, 120);
1275 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1276 "Fogged out quad has color %08x\n", color);
1278 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1280 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1281 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1282 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1283 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1285 else
1287 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1290 /* Test RANGEFOG vs FOGTABLEMODE */
1291 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1292 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1294 struct sVertex untransformed_3[] =
1296 {-1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1297 {-1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1298 { 1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1299 { 1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1303 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1304 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1305 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1308 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1310 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1311 * is not used, the fog coordinate will be equal to fogstart and the quad not
1312 * fogged. If range fog is used the fog coordinate will be slightly higher and
1313 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1314 * is calculated per vertex and interpolated, so even the center of the screen
1315 * where the difference doesn't matter will be fogged, but check the corners in
1316 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1317 start = 0.5f;
1318 end = 0.50001f;
1319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1320 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1322 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1324 /* Table fog: Range fog is not used */
1325 hr = IDirect3DDevice9_BeginScene(device);
1326 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1327 if (SUCCEEDED(hr))
1329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1330 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1332 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1333 hr = IDirect3DDevice9_EndScene(device);
1334 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1336 color = getPixelColor(device, 10, 10);
1337 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1338 color = getPixelColor(device, 630, 10);
1339 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1340 color = getPixelColor(device, 10, 470);
1341 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1342 color = getPixelColor(device, 630, 470);
1343 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1345 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1346 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1348 /* Vertex fog: Rangefog is used */
1349 hr = IDirect3DDevice9_BeginScene(device);
1350 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1351 if (SUCCEEDED(hr))
1353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1355 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1356 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1358 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1359 hr = IDirect3DDevice9_EndScene(device);
1360 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1362 color = getPixelColor(device, 10, 10);
1363 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1364 "Rangefog with vertex fog returned color 0x%08x\n", color);
1365 color = getPixelColor(device, 630, 10);
1366 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1367 "Rangefog with vertex fog returned color 0x%08x\n", color);
1368 color = getPixelColor(device, 10, 470);
1369 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1370 "Rangefog with vertex fog returned color 0x%08x\n", color);
1371 color = getPixelColor(device, 630, 470);
1372 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1373 "Rangefog with vertex fog returned color 0x%08x\n", color);
1375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1376 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1379 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1381 else
1383 skip("Range fog or table fog not supported, skipping range fog tests\n");
1386 /* Turn off the fog master switch to avoid confusing other tests */
1387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1388 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1390 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1392 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1395 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1396 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1397 * regardless of the actual addressing mode set. The way this test works is
1398 * that we sample in one of the corners of the cubemap with filtering enabled,
1399 * and check the interpolated color. There are essentially two reasonable
1400 * things an implementation can do: Either pick one of the faces and
1401 * interpolate the edge texel with itself (i.e., clamp within the face), or
1402 * interpolate between the edge texels of the three involved faces. It should
1403 * never involve the border color or the other side (texcoord wrapping) of a
1404 * face in the interpolation. */
1405 static void test_cube_wrap(IDirect3DDevice9 *device)
1407 static const float quad[][6] = {
1408 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1409 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1410 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1411 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1414 static const D3DVERTEXELEMENT9 decl_elements[] = {
1415 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1416 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1417 D3DDECL_END()
1420 static const struct {
1421 D3DTEXTUREADDRESS mode;
1422 const char *name;
1423 } address_modes[] = {
1424 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1425 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1426 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1427 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1428 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1431 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1432 IDirect3DCubeTexture9 *texture = NULL;
1433 IDirect3DSurface9 *surface = NULL;
1434 IDirect3DSurface9 *face_surface;
1435 D3DLOCKED_RECT locked_rect;
1436 HRESULT hr;
1437 UINT x;
1438 INT y, face;
1440 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1441 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1442 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1443 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1445 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1446 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1447 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1449 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1450 D3DPOOL_DEFAULT, &texture, NULL);
1451 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1453 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1454 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1456 for (y = 0; y < 128; ++y)
1458 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1459 for (x = 0; x < 64; ++x)
1461 *ptr++ = 0xff0000ff;
1463 for (x = 64; x < 128; ++x)
1465 *ptr++ = 0xffff0000;
1469 hr = IDirect3DSurface9_UnlockRect(surface);
1470 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1472 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1473 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1475 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1476 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1478 IDirect3DSurface9_Release(face_surface);
1480 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1481 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1483 for (y = 0; y < 128; ++y)
1485 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1486 for (x = 0; x < 64; ++x)
1488 *ptr++ = 0xffff0000;
1490 for (x = 64; x < 128; ++x)
1492 *ptr++ = 0xff0000ff;
1496 hr = IDirect3DSurface9_UnlockRect(surface);
1497 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1499 /* Create cube faces */
1500 for (face = 1; face < 6; ++face)
1502 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1503 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1505 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1506 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1508 IDirect3DSurface9_Release(face_surface);
1511 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1512 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1514 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1515 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1516 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1517 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1518 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1519 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1522 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1524 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1526 DWORD color;
1528 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1529 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1530 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1531 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1533 hr = IDirect3DDevice9_BeginScene(device);
1534 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1537 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1539 hr = IDirect3DDevice9_EndScene(device);
1540 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1542 color = getPixelColor(device, 320, 240);
1543 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1544 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1545 color, address_modes[x].name);
1547 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1548 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1550 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1551 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1554 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1555 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1557 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1558 IDirect3DCubeTexture9_Release(texture);
1559 IDirect3DSurface9_Release(surface);
1562 static void offscreen_test(IDirect3DDevice9 *device)
1564 HRESULT hr;
1565 IDirect3DTexture9 *offscreenTexture = NULL;
1566 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1567 DWORD color;
1569 static const float quad[][5] = {
1570 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1571 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1572 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1573 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1576 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1577 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1579 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1580 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1581 if(!offscreenTexture) {
1582 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1583 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1584 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1585 if(!offscreenTexture) {
1586 skip("Cannot create an offscreen render target\n");
1587 goto out;
1591 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1592 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1593 if(!backbuffer) {
1594 goto out;
1597 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1598 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1599 if(!offscreen) {
1600 goto out;
1603 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1604 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1606 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1607 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1608 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1609 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1610 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1611 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1612 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1613 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1615 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1617 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1618 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1619 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1621 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1623 /* Draw without textures - Should result in a white quad */
1624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1625 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1627 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1628 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1629 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1630 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1632 /* This time with the texture */
1633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1634 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1636 IDirect3DDevice9_EndScene(device);
1639 /* Center quad - should be white */
1640 color = getPixelColor(device, 320, 240);
1641 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1642 /* Some quad in the cleared part of the texture */
1643 color = getPixelColor(device, 170, 240);
1644 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1645 /* Part of the originally cleared back buffer */
1646 color = getPixelColor(device, 10, 10);
1647 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1648 if(0) {
1649 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1650 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1651 * the offscreen rendering mode this test would succeed or fail
1653 color = getPixelColor(device, 10, 470);
1654 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1657 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1659 out:
1660 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1661 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1663 /* restore things */
1664 if(backbuffer) {
1665 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1666 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1667 IDirect3DSurface9_Release(backbuffer);
1669 if(offscreenTexture) {
1670 IDirect3DTexture9_Release(offscreenTexture);
1672 if(offscreen) {
1673 IDirect3DSurface9_Release(offscreen);
1677 /* This test tests fog in combination with shaders.
1678 * What's tested: linear fog (vertex and table) with pixel shader
1679 * linear table fog with non foggy vertex shader
1680 * vertex fog with foggy vertex shader, non-linear
1681 * fog with shader, non-linear fog with foggy shader,
1682 * linear table fog with foggy shader
1684 static void fog_with_shader_test(IDirect3DDevice9 *device)
1686 HRESULT hr;
1687 DWORD color;
1688 union {
1689 float f;
1690 DWORD i;
1691 } start, end;
1692 unsigned int i, j;
1694 /* basic vertex shader without fog computation ("non foggy") */
1695 static const DWORD vertex_shader_code1[] = {
1696 0xfffe0101, /* vs_1_1 */
1697 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1698 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1699 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1700 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1701 0x0000ffff
1703 /* basic vertex shader with reversed fog computation ("foggy") */
1704 static const DWORD vertex_shader_code2[] = {
1705 0xfffe0101, /* vs_1_1 */
1706 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1707 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1708 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1709 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1710 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1711 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1712 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1713 0x0000ffff
1715 /* basic pixel shader */
1716 static const DWORD pixel_shader_code[] = {
1717 0xffff0101, /* ps_1_1 */
1718 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1719 0x0000ffff
1722 static struct vertex quad[] = {
1723 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1724 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1725 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1726 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1729 static const D3DVERTEXELEMENT9 decl_elements[] = {
1730 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1731 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1732 D3DDECL_END()
1735 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1736 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1737 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1739 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1740 static const struct test_data_t {
1741 int vshader;
1742 int pshader;
1743 D3DFOGMODE vfog;
1744 D3DFOGMODE tfog;
1745 unsigned int color[11];
1746 } test_data[] = {
1747 /* only pixel shader: */
1748 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1749 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1750 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1751 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1752 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1753 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1754 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1755 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1756 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1757 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1758 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1759 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1760 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1761 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1762 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1764 /* vertex shader */
1765 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1766 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1767 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1768 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1769 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1770 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1771 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1772 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1773 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1775 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1776 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1777 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1778 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1779 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1780 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1782 /* vertex shader and pixel shader */
1783 /* The next 4 tests would read the fog coord output, but it isn't available.
1784 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1785 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1786 * These tests should be disabled if some other hardware behaves differently
1788 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1789 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1790 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1791 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1792 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1793 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1794 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1795 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1796 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1797 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1798 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1799 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1801 /* These use the Z coordinate with linear table fog */
1802 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1803 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1806 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1809 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1815 /* Non-linear table fog without fog coord */
1816 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1817 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1818 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1819 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1820 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1821 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1823 #if 0 /* FIXME: these fail on GeForce 8500 */
1824 /* foggy vertex shader */
1825 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1826 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1827 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1828 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1829 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1830 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1831 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1832 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1833 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1834 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1835 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1836 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1837 #endif
1839 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1840 * all using the fixed fog-coord linear fog
1842 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1843 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1844 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1845 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1846 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1847 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1848 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1850 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1851 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1852 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1853 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1855 /* These use table fog. Here the shader-provided fog coordinate is
1856 * ignored and the z coordinate used instead
1858 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1859 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1860 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1861 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1862 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1863 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1864 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1865 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1866 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1869 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1870 start.f=0.1f;
1871 end.f=0.9f;
1873 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1874 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1875 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1876 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1877 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1878 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1879 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1880 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1882 /* Setup initial states: No lighting, fog on, fog color */
1883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1884 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1886 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1887 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1888 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1889 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1890 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1893 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1895 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1897 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1899 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1901 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1903 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1905 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1906 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1907 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1908 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1910 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1912 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1914 for(j=0; j < 11; j++)
1916 /* Don't use the whole zrange to prevent rounding errors */
1917 quad[0].z = 0.001f + (float)j / 10.02f;
1918 quad[1].z = 0.001f + (float)j / 10.02f;
1919 quad[2].z = 0.001f + (float)j / 10.02f;
1920 quad[3].z = 0.001f + (float)j / 10.02f;
1922 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1923 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1925 hr = IDirect3DDevice9_BeginScene(device);
1926 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1929 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1931 hr = IDirect3DDevice9_EndScene(device);
1932 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1934 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1935 color = getPixelColor(device, 128, 240);
1936 ok(color_match(color, test_data[i].color[j], 13),
1937 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1938 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1940 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1944 /* reset states */
1945 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1946 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1947 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1948 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1949 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1950 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1952 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1954 IDirect3DVertexShader9_Release(vertex_shader[1]);
1955 IDirect3DVertexShader9_Release(vertex_shader[2]);
1956 IDirect3DPixelShader9_Release(pixel_shader[1]);
1957 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1960 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1961 unsigned int i, x, y;
1962 HRESULT hr;
1963 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1964 D3DLOCKED_RECT locked_rect;
1966 /* Generate the textures */
1967 for(i=0; i<2; i++)
1969 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1970 D3DPOOL_MANAGED, &texture[i], NULL);
1971 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1973 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1974 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1975 for (y = 0; y < 128; ++y)
1977 if(i)
1978 { /* Set up black texture with 2x2 texel white spot in the middle */
1979 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1980 for (x = 0; x < 128; ++x)
1982 if(y>62 && y<66 && x>62 && x<66)
1983 *ptr++ = 0xffffffff;
1984 else
1985 *ptr++ = 0xff000000;
1988 else
1989 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1990 * (if multiplied with bumpenvmat)
1992 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1993 for (x = 0; x < 128; ++x)
1995 if(abs(x-64)>abs(y-64))
1997 if(x < 64)
1998 *ptr++ = 0xc000;
1999 else
2000 *ptr++ = 0x4000;
2002 else
2004 if(y < 64)
2005 *ptr++ = 0x0040;
2006 else
2007 *ptr++ = 0x00c0;
2012 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2013 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2015 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2016 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2018 /* Disable texture filtering */
2019 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2020 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2021 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2022 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2024 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2025 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2026 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2027 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2031 /* test the behavior of the texbem instruction
2032 * with normal 2D and projective 2D textures
2034 static void texbem_test(IDirect3DDevice9 *device)
2036 HRESULT hr;
2037 DWORD color;
2038 int i;
2040 static const DWORD pixel_shader_code[] = {
2041 0xffff0101, /* ps_1_1*/
2042 0x00000042, 0xb00f0000, /* tex t0*/
2043 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2044 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2045 0x0000ffff
2047 static const DWORD double_texbem_code[] = {
2048 0xffff0103, /* ps_1_3 */
2049 0x00000042, 0xb00f0000, /* tex t0 */
2050 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2051 0x00000042, 0xb00f0002, /* tex t2 */
2052 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2053 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2054 0x0000ffff /* end */
2058 static const float quad[][7] = {
2059 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2060 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2061 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2062 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2064 static const float quad_proj[][9] = {
2065 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2066 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2067 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2068 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2071 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2072 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2073 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2074 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2075 D3DDECL_END()
2077 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2078 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2079 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2080 D3DDECL_END()
2081 } };
2083 /* use asymmetric matrix to test loading */
2084 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2086 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2087 IDirect3DPixelShader9 *pixel_shader = NULL;
2088 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
2089 D3DLOCKED_RECT locked_rect;
2091 generate_bumpmap_textures(device);
2093 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2094 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2095 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2096 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2097 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2099 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2100 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2103 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2105 for(i=0; i<2; i++)
2107 if(i)
2109 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2110 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2114 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2115 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2116 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2118 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2119 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2120 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2121 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2123 hr = IDirect3DDevice9_BeginScene(device);
2124 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2126 if(!i)
2127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2128 else
2129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2132 hr = IDirect3DDevice9_EndScene(device);
2133 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2135 color = getPixelColor(device, 320-32, 240);
2136 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2137 color = getPixelColor(device, 320+32, 240);
2138 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2139 color = getPixelColor(device, 320, 240-32);
2140 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2141 color = getPixelColor(device, 320, 240+32);
2142 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2145 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2147 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2148 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2149 IDirect3DPixelShader9_Release(pixel_shader);
2151 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2152 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2153 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2156 /* clean up */
2157 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2158 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2160 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2161 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2163 for(i=0; i<2; i++)
2165 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2166 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2167 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2168 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2169 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2170 IDirect3DTexture9_Release(texture);
2173 /* Test double texbem */
2174 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2175 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2176 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2177 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2178 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2179 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2180 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2181 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2183 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2184 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2185 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2186 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2188 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2189 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2191 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2192 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2193 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2194 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2195 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2196 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2199 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2200 #define tex 0x00ff0000
2201 #define tex1 0x0000ff00
2202 #define origin 0x000000ff
2203 static const DWORD pixel_data[] = {
2204 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2205 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2206 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2207 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2208 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2209 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2210 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2211 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2213 #undef tex1
2214 #undef tex2
2215 #undef origin
2217 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2218 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2219 for(i = 0; i < 8; i++) {
2220 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2222 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2223 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2226 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2227 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2228 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2229 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2230 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2231 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2232 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2233 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2234 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2235 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2236 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2237 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2239 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2240 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2241 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2242 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2243 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2245 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2247 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2250 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2251 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2252 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2253 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2254 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2256 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2258 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2261 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2262 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2263 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2264 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2265 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2266 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2267 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2268 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2269 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2270 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2271 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2272 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2273 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2274 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2275 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2276 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2278 hr = IDirect3DDevice9_BeginScene(device);
2279 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2280 if(SUCCEEDED(hr)) {
2281 static const float double_quad[] = {
2282 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2283 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2284 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2285 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2289 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2290 hr = IDirect3DDevice9_EndScene(device);
2291 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2293 color = getPixelColor(device, 320, 240);
2294 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2296 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2297 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2298 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2299 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2300 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2302 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2303 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2304 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2305 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2307 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2308 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2310 IDirect3DPixelShader9_Release(pixel_shader);
2311 IDirect3DTexture9_Release(texture);
2312 IDirect3DTexture9_Release(texture1);
2313 IDirect3DTexture9_Release(texture2);
2316 static void z_range_test(IDirect3DDevice9 *device)
2318 const struct vertex quad[] =
2320 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2321 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2322 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2323 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2325 const struct vertex quad2[] =
2327 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2328 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2329 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2330 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2333 const struct tvertex quad3[] =
2335 { 0, 240, 1.1f, 1.0, 0xffffff00},
2336 { 0, 480, 1.1f, 1.0, 0xffffff00},
2337 { 640, 240, -1.1f, 1.0, 0xffffff00},
2338 { 640, 480, -1.1f, 1.0, 0xffffff00},
2340 const struct tvertex quad4[] =
2342 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2343 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2344 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2345 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2347 HRESULT hr;
2348 DWORD color;
2349 IDirect3DVertexShader9 *shader;
2350 IDirect3DVertexDeclaration9 *decl;
2351 D3DCAPS9 caps;
2352 const DWORD shader_code[] = {
2353 0xfffe0101, /* vs_1_1 */
2354 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2355 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2356 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2357 0x0000ffff /* end */
2359 static const D3DVERTEXELEMENT9 decl_elements[] = {
2360 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2361 D3DDECL_END()
2364 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2366 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2367 * then call Present. Then clear the color buffer to make sure it has some defined content
2368 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2369 * by the depth value.
2371 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2372 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2374 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2376 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2379 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2381 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2383 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2385 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2386 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2387 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2389 hr = IDirect3DDevice9_BeginScene(device);
2390 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2391 if(hr == D3D_OK)
2393 /* Test the untransformed vertex path */
2394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2395 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2401 /* Test the transformed vertex path */
2402 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2403 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2406 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2408 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2410 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2412 hr = IDirect3DDevice9_EndScene(device);
2413 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2416 /* Do not test the exact corner pixels, but go pretty close to them */
2418 /* Clipped because z > 1.0 */
2419 color = getPixelColor(device, 28, 238);
2420 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2421 color = getPixelColor(device, 28, 241);
2422 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2424 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2426 else
2428 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2431 /* Not clipped, > z buffer clear value(0.75) */
2432 color = getPixelColor(device, 31, 238);
2433 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2434 color = getPixelColor(device, 31, 241);
2435 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2436 color = getPixelColor(device, 100, 238);
2437 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2438 color = getPixelColor(device, 100, 241);
2439 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2441 /* Not clipped, < z buffer clear value */
2442 color = getPixelColor(device, 104, 238);
2443 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2444 color = getPixelColor(device, 104, 241);
2445 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2446 color = getPixelColor(device, 318, 238);
2447 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2448 color = getPixelColor(device, 318, 241);
2449 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2451 /* Clipped because z < 0.0 */
2452 color = getPixelColor(device, 321, 238);
2453 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2454 color = getPixelColor(device, 321, 241);
2455 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2457 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2459 else
2461 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2465 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2467 /* Test the shader path */
2468 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2469 skip("Vertex shaders not supported\n");
2470 goto out;
2472 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2473 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2474 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2475 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2477 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2479 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2480 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2481 IDirect3DDevice9_SetVertexShader(device, shader);
2482 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2484 hr = IDirect3DDevice9_BeginScene(device);
2485 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2486 if(hr == D3D_OK)
2488 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2489 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2490 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2492 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2493 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2494 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2495 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2497 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2499 hr = IDirect3DDevice9_EndScene(device);
2500 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2503 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2504 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2505 IDirect3DDevice9_SetVertexShader(device, NULL);
2506 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2508 IDirect3DVertexDeclaration9_Release(decl);
2509 IDirect3DVertexShader9_Release(shader);
2511 /* Z < 1.0 */
2512 color = getPixelColor(device, 28, 238);
2513 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2515 /* 1.0 < z < 0.75 */
2516 color = getPixelColor(device, 31, 238);
2517 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2518 color = getPixelColor(device, 100, 238);
2519 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2521 /* 0.75 < z < 0.0 */
2522 color = getPixelColor(device, 104, 238);
2523 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2524 color = getPixelColor(device, 318, 238);
2525 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2527 /* 0.0 < z */
2528 color = getPixelColor(device, 321, 238);
2529 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2531 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2532 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2534 out:
2535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2536 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2538 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2539 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2540 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2543 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2545 D3DSURFACE_DESC desc;
2546 D3DLOCKED_RECT l;
2547 HRESULT hr;
2548 unsigned int x, y;
2549 DWORD *mem;
2551 memset(&desc, 0, sizeof(desc));
2552 memset(&l, 0, sizeof(l));
2553 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2554 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2555 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2556 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2557 if(FAILED(hr)) return;
2559 for(y = 0; y < desc.Height; y++)
2561 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2562 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2564 mem[x] = color;
2567 hr = IDirect3DSurface9_UnlockRect(surface);
2568 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2571 /* This tests a variety of possible StretchRect() situations */
2572 static void stretchrect_test(IDirect3DDevice9 *device)
2574 HRESULT hr;
2575 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2576 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2577 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2578 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2579 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2580 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2581 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2582 IDirect3DSurface9 *orig_rt = NULL;
2583 IDirect3DSurface9 *backbuffer = NULL;
2584 DWORD color;
2586 RECT src_rect64 = {0, 0, 64, 64};
2587 RECT src_rect64_flipy = {0, 64, 64, 0};
2588 RECT dst_rect64 = {0, 0, 64, 64};
2589 RECT dst_rect64_flipy = {0, 64, 64, 0};
2591 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2592 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2593 if(!orig_rt) {
2594 goto out;
2597 /* Create our temporary surfaces in system memory */
2598 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2599 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2600 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2601 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2603 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2604 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2605 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2606 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2607 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2608 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2609 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2611 /* Create render target surfaces */
2612 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2613 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2614 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2615 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2616 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2617 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2618 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2619 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2621 /* Create render target textures */
2622 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2623 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2624 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2625 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2626 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2627 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2628 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2629 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2630 if (tex_rt32) {
2631 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2632 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2634 if (tex_rt64) {
2635 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2636 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2638 if (tex_rt_dest64) {
2639 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2640 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2642 if (tex_rt_dest64) {
2643 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2644 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2647 /* Create regular textures in D3DPOOL_DEFAULT */
2648 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2649 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2650 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2651 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2652 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2653 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2654 if (tex32) {
2655 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2656 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2658 if (tex64) {
2659 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2660 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2662 if (tex_dest64) {
2663 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2664 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2667 /*********************************************************************
2668 * Tests for when the source parameter is an offscreen plain surface *
2669 *********************************************************************/
2671 /* Fill the offscreen 64x64 surface with green */
2672 if (surf_offscreen64)
2673 fill_surface(surf_offscreen64, 0xff00ff00);
2675 /* offscreenplain ==> offscreenplain, same size */
2676 if(surf_offscreen64 && surf_offscreen_dest64) {
2677 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2678 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2680 if (hr == D3D_OK) {
2681 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2682 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2685 /* Blit without scaling */
2686 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2687 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2690 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2691 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2694 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2695 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2698 /* offscreenplain ==> rendertarget texture, same size */
2699 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2700 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2701 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703 /* We can't lock rendertarget textures, so copy to our temp surface first */
2704 if (hr == D3D_OK) {
2705 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2706 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2709 if (hr == D3D_OK) {
2710 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2711 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2714 /* Blit without scaling */
2715 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2716 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2718 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2719 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2720 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2722 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2723 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2724 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2727 /* offscreenplain ==> rendertarget surface, same size */
2728 if(surf_offscreen64 && surf_rt_dest64) {
2729 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2730 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2732 if (hr == D3D_OK) {
2733 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2734 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2737 /* Blit without scaling */
2738 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2739 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2741 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2742 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2743 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2745 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2746 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2747 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2750 /* offscreenplain ==> texture, same size (should fail) */
2751 if(surf_offscreen64 && surf_tex_dest64) {
2752 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2753 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2756 /* Fill the smaller offscreen surface with red */
2757 fill_surface(surf_offscreen32, 0xffff0000);
2759 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2760 if(surf_offscreen32 && surf_offscreen64) {
2761 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2762 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2765 /* offscreenplain ==> rendertarget texture, scaling */
2766 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2767 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2768 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2770 /* We can't lock rendertarget textures, so copy to our temp surface first */
2771 if (hr == D3D_OK) {
2772 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2773 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2776 if (hr == D3D_OK) {
2777 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2778 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2782 /* offscreenplain ==> rendertarget surface, scaling */
2783 if(surf_offscreen32 && surf_rt_dest64) {
2784 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2785 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2787 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2788 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2791 /* offscreenplain ==> texture, scaling (should fail) */
2792 if(surf_offscreen32 && surf_tex_dest64) {
2793 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2794 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2797 /************************************************************
2798 * Tests for when the source parameter is a regular texture *
2799 ************************************************************/
2801 /* Fill the surface of the regular texture with blue */
2802 if (surf_tex64 && surf_temp64) {
2803 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2804 fill_surface(surf_temp64, 0xff0000ff);
2805 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2806 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2809 /* texture ==> offscreenplain, same size */
2810 if(surf_tex64 && surf_offscreen64) {
2811 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2812 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2815 /* texture ==> rendertarget texture, same size */
2816 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2817 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2818 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2820 /* We can't lock rendertarget textures, so copy to our temp surface first */
2821 if (hr == D3D_OK) {
2822 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2823 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2826 if (hr == D3D_OK) {
2827 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2828 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2831 /* Blit without scaling */
2832 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2833 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2836 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2837 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2839 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2840 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2841 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2844 /* texture ==> rendertarget surface, same size */
2845 if(surf_tex64 && surf_rt_dest64) {
2846 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2847 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2849 if (hr == D3D_OK) {
2850 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2851 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2854 /* Blit without scaling */
2855 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_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_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2860 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_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2864 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2867 /* texture ==> texture, same size (should fail) */
2868 if(surf_tex64 && surf_tex_dest64) {
2869 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2870 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2873 /* Fill the surface of the smaller regular texture with red */
2874 if (surf_tex32 && surf_temp32) {
2875 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2876 fill_surface(surf_temp32, 0xffff0000);
2877 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2878 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2881 /* texture ==> offscreenplain, scaling (should fail) */
2882 if(surf_tex32 && surf_offscreen64) {
2883 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2884 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2887 /* texture ==> rendertarget texture, scaling */
2888 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2889 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2890 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2892 /* We can't lock rendertarget textures, so copy to our temp surface first */
2893 if (hr == D3D_OK) {
2894 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2895 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2898 if (hr == D3D_OK) {
2899 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2900 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2904 /* texture ==> rendertarget surface, scaling */
2905 if(surf_tex32 && surf_rt_dest64) {
2906 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2907 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2909 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2910 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2913 /* texture ==> texture, scaling (should fail) */
2914 if(surf_tex32 && surf_tex_dest64) {
2915 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2916 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2919 /*****************************************************************
2920 * Tests for when the source parameter is a rendertarget texture *
2921 *****************************************************************/
2923 /* Fill the surface of the rendertarget texture with white */
2924 if (surf_tex_rt64 && surf_temp64) {
2925 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2926 fill_surface(surf_temp64, 0xffffffff);
2927 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2928 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2931 /* rendertarget texture ==> offscreenplain, same size */
2932 if(surf_tex_rt64 && surf_offscreen64) {
2933 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2934 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2937 /* rendertarget texture ==> rendertarget texture, same size */
2938 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2939 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2940 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2942 /* We can't lock rendertarget textures, so copy to our temp surface first */
2943 if (hr == D3D_OK) {
2944 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2945 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2948 if (hr == D3D_OK) {
2949 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2950 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2953 /* Blit without scaling */
2954 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2955 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2957 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2958 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2959 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2961 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2962 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2963 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2966 /* rendertarget texture ==> rendertarget surface, same size */
2967 if(surf_tex_rt64 && surf_rt_dest64) {
2968 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2969 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2971 if (hr == D3D_OK) {
2972 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2973 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2976 /* Blit without scaling */
2977 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2978 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2980 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2981 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2982 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2984 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2985 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2986 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2989 /* rendertarget texture ==> texture, same size (should fail) */
2990 if(surf_tex_rt64 && surf_tex_dest64) {
2991 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2992 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2995 /* Fill the surface of the smaller rendertarget texture with red */
2996 if (surf_tex_rt32 && surf_temp32) {
2997 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2998 fill_surface(surf_temp32, 0xffff0000);
2999 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3000 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3003 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3004 if(surf_tex_rt32 && surf_offscreen64) {
3005 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3006 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3009 /* rendertarget texture ==> rendertarget texture, scaling */
3010 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3011 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3012 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3014 /* We can't lock rendertarget textures, so copy to our temp surface first */
3015 if (hr == D3D_OK) {
3016 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3017 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3020 if (hr == D3D_OK) {
3021 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3022 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3026 /* rendertarget texture ==> rendertarget surface, scaling */
3027 if(surf_tex_rt32 && surf_rt_dest64) {
3028 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3029 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3031 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3032 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3035 /* rendertarget texture ==> texture, scaling (should fail) */
3036 if(surf_tex_rt32 && surf_tex_dest64) {
3037 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3038 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3041 /*****************************************************************
3042 * Tests for when the source parameter is a rendertarget surface *
3043 *****************************************************************/
3045 /* Fill the surface of the rendertarget surface with black */
3046 if (surf_rt64)
3047 fill_surface(surf_rt64, 0xff000000);
3049 /* rendertarget texture ==> offscreenplain, same size */
3050 if(surf_rt64 && surf_offscreen64) {
3051 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3052 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3055 /* rendertarget surface ==> rendertarget texture, same size */
3056 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3057 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3058 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3060 /* We can't lock rendertarget textures, so copy to our temp surface first */
3061 if (hr == D3D_OK) {
3062 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3063 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3066 if (hr == D3D_OK) {
3067 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3068 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3071 /* Blit without scaling */
3072 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3073 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3075 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3076 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3077 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3079 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3080 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3081 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3084 /* rendertarget surface ==> rendertarget surface, same size */
3085 if(surf_rt64 && surf_rt_dest64) {
3086 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3087 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3089 if (hr == D3D_OK) {
3090 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3091 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3094 /* Blit without scaling */
3095 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3096 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3098 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3099 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3100 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3102 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3103 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3104 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3107 /* rendertarget surface ==> texture, same size (should fail) */
3108 if(surf_rt64 && surf_tex_dest64) {
3109 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3110 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3113 /* Fill the surface of the smaller rendertarget texture with red */
3114 if (surf_rt32)
3115 fill_surface(surf_rt32, 0xffff0000);
3117 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3118 if(surf_rt32 && surf_offscreen64) {
3119 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3120 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3123 /* rendertarget surface ==> rendertarget texture, scaling */
3124 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3125 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3126 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3128 /* We can't lock rendertarget textures, so copy to our temp surface first */
3129 if (hr == D3D_OK) {
3130 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3131 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3134 if (hr == D3D_OK) {
3135 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3136 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3140 /* rendertarget surface ==> rendertarget surface, scaling */
3141 if(surf_rt32 && surf_rt_dest64) {
3142 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3143 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3145 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3146 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3149 /* rendertarget surface ==> texture, scaling (should fail) */
3150 if(surf_rt32 && surf_tex_dest64) {
3151 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3152 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3155 /* backbuffer ==> surface tests (no scaling) */
3156 if(backbuffer && surf_tex_rt_dest640_480)
3158 RECT src_rect = {0, 0, 640, 480};
3159 RECT src_rect_flipy = {0, 480, 640, 0};
3160 RECT dst_rect = {0, 0, 640, 480};
3161 RECT dst_rect_flipy = {0, 480, 640, 0};
3163 /* Blit with NULL rectangles */
3164 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3165 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3167 /* Blit without scaling */
3168 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3169 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3171 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3172 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3173 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3175 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3176 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3177 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3180 /* TODO: Test format conversions */
3183 out:
3184 /* Clean up */
3185 if (backbuffer)
3186 IDirect3DSurface9_Release(backbuffer);
3187 if (surf_rt32)
3188 IDirect3DSurface9_Release(surf_rt32);
3189 if (surf_rt64)
3190 IDirect3DSurface9_Release(surf_rt64);
3191 if (surf_rt_dest64)
3192 IDirect3DSurface9_Release(surf_rt_dest64);
3193 if (surf_temp32)
3194 IDirect3DSurface9_Release(surf_temp32);
3195 if (surf_temp64)
3196 IDirect3DSurface9_Release(surf_temp64);
3197 if (surf_offscreen32)
3198 IDirect3DSurface9_Release(surf_offscreen32);
3199 if (surf_offscreen64)
3200 IDirect3DSurface9_Release(surf_offscreen64);
3201 if (surf_offscreen_dest64)
3202 IDirect3DSurface9_Release(surf_offscreen_dest64);
3204 if (tex_rt32) {
3205 if (surf_tex_rt32)
3206 IDirect3DSurface9_Release(surf_tex_rt32);
3207 IDirect3DTexture9_Release(tex_rt32);
3209 if (tex_rt64) {
3210 if (surf_tex_rt64)
3211 IDirect3DSurface9_Release(surf_tex_rt64);
3212 IDirect3DTexture9_Release(tex_rt64);
3214 if (tex_rt_dest64) {
3215 if (surf_tex_rt_dest64)
3216 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3217 IDirect3DTexture9_Release(tex_rt_dest64);
3219 if (tex_rt_dest640_480) {
3220 if (surf_tex_rt_dest640_480)
3221 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3222 IDirect3DTexture9_Release(tex_rt_dest640_480);
3224 if (tex32) {
3225 if (surf_tex32)
3226 IDirect3DSurface9_Release(surf_tex32);
3227 IDirect3DTexture9_Release(tex32);
3229 if (tex64) {
3230 if (surf_tex64)
3231 IDirect3DSurface9_Release(surf_tex64);
3232 IDirect3DTexture9_Release(tex64);
3234 if (tex_dest64) {
3235 if (surf_tex_dest64)
3236 IDirect3DSurface9_Release(surf_tex_dest64);
3237 IDirect3DTexture9_Release(tex_dest64);
3240 if (orig_rt) {
3241 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3242 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3243 IDirect3DSurface9_Release(orig_rt);
3247 static void maxmip_test(IDirect3DDevice9 *device)
3249 IDirect3DTexture9 *texture = NULL;
3250 IDirect3DSurface9 *surface = NULL;
3251 HRESULT hr;
3252 DWORD color;
3253 static const struct
3255 struct
3257 float x, y, z;
3258 float s, t;
3260 v[4];
3262 quads[] =
3265 {-1.0, -1.0, 0.0, 0.0, 0.0},
3266 {-1.0, 0.0, 0.0, 0.0, 1.0},
3267 { 0.0, -1.0, 0.0, 1.0, 0.0},
3268 { 0.0, 0.0, 0.0, 1.0, 1.0},
3271 { 0.0, -1.0, 0.0, 0.0, 0.0},
3272 { 0.0, 0.0, 0.0, 0.0, 1.0},
3273 { 1.0, -1.0, 0.0, 1.0, 0.0},
3274 { 1.0, 0.0, 0.0, 1.0, 1.0},
3277 { 0.0, 0.0, 0.0, 0.0, 0.0},
3278 { 0.0, 1.0, 0.0, 0.0, 1.0},
3279 { 1.0, 0.0, 0.0, 1.0, 0.0},
3280 { 1.0, 1.0, 0.0, 1.0, 1.0},
3283 {-1.0, 0.0, 0.0, 0.0, 0.0},
3284 {-1.0, 1.0, 0.0, 0.0, 1.0},
3285 { 0.0, 0.0, 0.0, 1.0, 0.0},
3286 { 0.0, 1.0, 0.0, 1.0, 1.0},
3290 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3291 &texture, NULL);
3292 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3293 if(!texture)
3295 skip("Failed to create test texture\n");
3296 return;
3299 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3300 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3301 fill_surface(surface, 0xffff0000);
3302 IDirect3DSurface9_Release(surface);
3303 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3304 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3305 fill_surface(surface, 0xff00ff00);
3306 IDirect3DSurface9_Release(surface);
3307 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3308 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3309 fill_surface(surface, 0xff0000ff);
3310 IDirect3DSurface9_Release(surface);
3312 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3313 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3314 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3315 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3317 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3318 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3320 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3321 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3323 hr = IDirect3DDevice9_BeginScene(device);
3324 if(SUCCEEDED(hr))
3326 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3327 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3329 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3331 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3332 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3333 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3334 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3336 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3337 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3339 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3341 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3342 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3344 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3345 hr = IDirect3DDevice9_EndScene(device);
3346 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3349 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3350 color = getPixelColor(device, 160, 360);
3351 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3352 color = getPixelColor(device, 480, 360);
3353 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3354 color = getPixelColor(device, 480, 120);
3355 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3356 color = getPixelColor(device, 160, 120);
3357 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3359 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3362 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3367 hr = IDirect3DDevice9_BeginScene(device);
3368 if(SUCCEEDED(hr))
3370 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3373 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3376 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3378 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3380 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3381 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3383 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3385 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3386 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3389 hr = IDirect3DDevice9_EndScene(device);
3390 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3393 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3394 * level 3 (> levels in texture) samples from the highest level in the
3395 * texture (level 2). */
3396 color = getPixelColor(device, 160, 360);
3397 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3398 color = getPixelColor(device, 480, 360);
3399 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3400 color = getPixelColor(device, 480, 120);
3401 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3402 color = getPixelColor(device, 160, 120);
3403 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3404 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3405 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3407 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3408 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3410 hr = IDirect3DDevice9_BeginScene(device);
3411 if(SUCCEEDED(hr))
3413 DWORD ret;
3415 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3416 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3417 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3418 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3419 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3420 ret = IDirect3DTexture9_SetLOD(texture, 1);
3421 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3423 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3425 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3426 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3427 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3428 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3429 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3430 ret = IDirect3DTexture9_SetLOD(texture, 2);
3431 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3433 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3435 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3436 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3437 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3438 ret = IDirect3DTexture9_SetLOD(texture, 1);
3439 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3441 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3443 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3444 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3445 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3446 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3447 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3448 ret = IDirect3DTexture9_SetLOD(texture, 1);
3449 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3450 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3451 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452 hr = IDirect3DDevice9_EndScene(device);
3453 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3456 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3457 * level 3 (> levels in texture) samples from the highest level in the
3458 * texture (level 2). */
3459 color = getPixelColor(device, 160, 360);
3460 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3461 color = getPixelColor(device, 480, 360);
3462 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3463 color = getPixelColor(device, 480, 120);
3464 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3465 color = getPixelColor(device, 160, 120);
3466 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3469 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3471 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3472 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3473 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3474 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3476 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3477 IDirect3DTexture9_Release(texture);
3480 static void release_buffer_test(IDirect3DDevice9 *device)
3482 IDirect3DVertexBuffer9 *vb = NULL;
3483 IDirect3DIndexBuffer9 *ib = NULL;
3484 HRESULT hr;
3485 BYTE *data;
3486 LONG ref;
3488 static const struct vertex quad[] = {
3489 {-1.0, -1.0, 0.1, 0xffff0000},
3490 {-1.0, 1.0, 0.1, 0xffff0000},
3491 { 1.0, 1.0, 0.1, 0xffff0000},
3493 {-1.0, -1.0, 0.1, 0xff00ff00},
3494 {-1.0, 1.0, 0.1, 0xff00ff00},
3495 { 1.0, 1.0, 0.1, 0xff00ff00}
3497 short indices[] = {3, 4, 5};
3499 /* Index and vertex buffers should always be creatable */
3500 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3501 D3DPOOL_MANAGED, &vb, NULL);
3502 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3503 if(!vb) {
3504 skip("Failed to create a vertex buffer\n");
3505 return;
3507 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3508 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3509 if(!ib) {
3510 skip("Failed to create an index buffer\n");
3511 return;
3514 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3515 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3516 memcpy(data, quad, sizeof(quad));
3517 hr = IDirect3DVertexBuffer9_Unlock(vb);
3518 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3520 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3521 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3522 memcpy(data, indices, sizeof(indices));
3523 hr = IDirect3DIndexBuffer9_Unlock(ib);
3524 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3526 hr = IDirect3DDevice9_SetIndices(device, ib);
3527 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3528 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3529 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3530 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3531 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3533 /* Now destroy the bound index buffer and draw again */
3534 ref = IDirect3DIndexBuffer9_Release(ib);
3535 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3537 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3538 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3540 hr = IDirect3DDevice9_BeginScene(device);
3541 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3542 if(SUCCEEDED(hr))
3544 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3545 * making assumptions about the indices or vertices
3547 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3548 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3549 hr = IDirect3DDevice9_EndScene(device);
3550 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3553 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3554 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3556 hr = IDirect3DDevice9_SetIndices(device, NULL);
3557 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3558 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3559 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3561 /* Index buffer was already destroyed as part of the test */
3562 IDirect3DVertexBuffer9_Release(vb);
3565 static void float_texture_test(IDirect3DDevice9 *device)
3567 IDirect3D9 *d3d = NULL;
3568 HRESULT hr;
3569 IDirect3DTexture9 *texture = NULL;
3570 D3DLOCKED_RECT lr;
3571 float *data;
3572 DWORD color;
3573 float quad[] = {
3574 -1.0, -1.0, 0.1, 0.0, 0.0,
3575 -1.0, 1.0, 0.1, 0.0, 1.0,
3576 1.0, -1.0, 0.1, 1.0, 0.0,
3577 1.0, 1.0, 0.1, 1.0, 1.0,
3580 memset(&lr, 0, sizeof(lr));
3581 IDirect3DDevice9_GetDirect3D(device, &d3d);
3582 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3583 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3584 skip("D3DFMT_R32F textures not supported\n");
3585 goto out;
3588 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3589 D3DPOOL_MANAGED, &texture, NULL);
3590 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3591 if(!texture) {
3592 skip("Failed to create R32F texture\n");
3593 goto out;
3596 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3597 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3598 data = lr.pBits;
3599 *data = 0.0;
3600 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3601 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3603 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3604 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3606 hr = IDirect3DDevice9_BeginScene(device);
3607 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3608 if(SUCCEEDED(hr))
3610 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3611 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3614 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3616 hr = IDirect3DDevice9_EndScene(device);
3617 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3619 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3622 color = getPixelColor(device, 240, 320);
3623 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3626 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3628 out:
3629 if(texture) IDirect3DTexture9_Release(texture);
3630 IDirect3D9_Release(d3d);
3633 static void g16r16_texture_test(IDirect3DDevice9 *device)
3635 IDirect3D9 *d3d = NULL;
3636 HRESULT hr;
3637 IDirect3DTexture9 *texture = NULL;
3638 D3DLOCKED_RECT lr;
3639 DWORD *data;
3640 DWORD color;
3641 float quad[] = {
3642 -1.0, -1.0, 0.1, 0.0, 0.0,
3643 -1.0, 1.0, 0.1, 0.0, 1.0,
3644 1.0, -1.0, 0.1, 1.0, 0.0,
3645 1.0, 1.0, 0.1, 1.0, 1.0,
3648 memset(&lr, 0, sizeof(lr));
3649 IDirect3DDevice9_GetDirect3D(device, &d3d);
3650 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3651 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3652 skip("D3DFMT_G16R16 textures not supported\n");
3653 goto out;
3656 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3657 D3DPOOL_MANAGED, &texture, NULL);
3658 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3659 if(!texture) {
3660 skip("Failed to create D3DFMT_G16R16 texture\n");
3661 goto out;
3664 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3665 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3666 data = lr.pBits;
3667 *data = 0x0f00f000;
3668 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3669 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3671 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3674 hr = IDirect3DDevice9_BeginScene(device);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3676 if(SUCCEEDED(hr))
3678 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3679 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3682 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3684 hr = IDirect3DDevice9_EndScene(device);
3685 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3687 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3688 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3690 color = getPixelColor(device, 240, 320);
3691 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3692 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3695 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3697 out:
3698 if(texture) IDirect3DTexture9_Release(texture);
3699 IDirect3D9_Release(d3d);
3702 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3704 HRESULT hr;
3705 IDirect3D9 *d3d;
3706 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3707 D3DCAPS9 caps;
3708 IDirect3DTexture9 *texture = NULL;
3709 IDirect3DVolumeTexture9 *volume = NULL;
3710 unsigned int x, y, z;
3711 D3DLOCKED_RECT lr;
3712 D3DLOCKED_BOX lb;
3713 DWORD color;
3714 UINT w, h;
3715 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3716 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3717 0.0, 1.0, 0.0, 0.0,
3718 0.0, 0.0, 1.0, 0.0,
3719 0.0, 0.0, 0.0, 1.0};
3720 static const D3DVERTEXELEMENT9 decl_elements[] = {
3721 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3722 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3723 D3DDECL_END()
3725 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3726 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3727 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3728 D3DDECL_END()
3730 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3731 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3732 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3733 D3DDECL_END()
3735 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3736 0x00, 0xff, 0x00, 0x00,
3737 0x00, 0x00, 0x00, 0x00,
3738 0x00, 0x00, 0x00, 0x00};
3740 memset(&lr, 0, sizeof(lr));
3741 memset(&lb, 0, sizeof(lb));
3742 IDirect3DDevice9_GetDirect3D(device, &d3d);
3743 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3744 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3745 fmt = D3DFMT_A16B16G16R16;
3747 IDirect3D9_Release(d3d);
3749 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3750 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3751 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3753 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3754 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3755 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3756 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3757 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3758 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3759 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3761 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3762 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3763 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3764 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3765 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3767 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3768 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3772 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3774 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3775 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3776 w = min(1024, caps.MaxTextureWidth);
3777 h = min(1024, caps.MaxTextureHeight);
3778 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3779 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3781 if(!texture) {
3782 skip("Failed to create the test texture\n");
3783 return;
3786 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3787 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3788 * 1.0 in red and green for the x and y coords
3790 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3791 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3792 for(y = 0; y < h; y++) {
3793 for(x = 0; x < w; x++) {
3794 double r_f = (double) y / (double) h;
3795 double g_f = (double) x / (double) w;
3796 if(fmt == D3DFMT_A16B16G16R16) {
3797 unsigned short r, g;
3798 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3799 r = (unsigned short) (r_f * 65536.0);
3800 g = (unsigned short) (g_f * 65536.0);
3801 dst[0] = r;
3802 dst[1] = g;
3803 dst[2] = 0;
3804 dst[3] = 65535;
3805 } else {
3806 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3807 unsigned char r = (unsigned char) (r_f * 255.0);
3808 unsigned char g = (unsigned char) (g_f * 255.0);
3809 dst[0] = 0;
3810 dst[1] = g;
3811 dst[2] = r;
3812 dst[3] = 255;
3816 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3817 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3818 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3819 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3821 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3822 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3823 hr = IDirect3DDevice9_BeginScene(device);
3824 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3825 if(SUCCEEDED(hr))
3827 float quad1[] = {
3828 -1.0, -1.0, 0.1, 1.0, 1.0,
3829 -1.0, 0.0, 0.1, 1.0, 1.0,
3830 0.0, -1.0, 0.1, 1.0, 1.0,
3831 0.0, 0.0, 0.1, 1.0, 1.0,
3833 float quad2[] = {
3834 -1.0, 0.0, 0.1, 1.0, 1.0,
3835 -1.0, 1.0, 0.1, 1.0, 1.0,
3836 0.0, 0.0, 0.1, 1.0, 1.0,
3837 0.0, 1.0, 0.1, 1.0, 1.0,
3839 float quad3[] = {
3840 0.0, 0.0, 0.1, 0.5, 0.5,
3841 0.0, 1.0, 0.1, 0.5, 0.5,
3842 1.0, 0.0, 0.1, 0.5, 0.5,
3843 1.0, 1.0, 0.1, 0.5, 0.5,
3845 float quad4[] = {
3846 320, 480, 0.1, 1.0, 0.0, 1.0,
3847 320, 240, 0.1, 1.0, 0.0, 1.0,
3848 640, 480, 0.1, 1.0, 0.0, 1.0,
3849 640, 240, 0.1, 1.0, 0.0, 1.0,
3851 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3852 0.0, 0.0, 0.0, 0.0,
3853 0.0, 0.0, 0.0, 0.0,
3854 0.0, 0.0, 0.0, 0.0};
3856 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3857 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3858 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3860 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3862 /* What happens with transforms enabled? */
3863 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3864 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3865 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3866 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3868 /* What happens if 4 coords are used, but only 2 given ?*/
3869 mat[8] = 1.0;
3870 mat[13] = 1.0;
3871 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3872 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3873 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3874 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3876 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3878 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3879 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3880 * due to the coords in the vertices. (turns out red, indeed)
3882 memset(mat, 0, sizeof(mat));
3883 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3884 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3886 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3887 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3888 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3890 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3892 hr = IDirect3DDevice9_EndScene(device);
3893 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3895 color = getPixelColor(device, 160, 360);
3896 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3897 color = getPixelColor(device, 160, 120);
3898 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3899 color = getPixelColor(device, 480, 120);
3900 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3901 color = getPixelColor(device, 480, 360);
3902 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3903 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3907 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3909 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3910 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3911 hr = IDirect3DDevice9_BeginScene(device);
3912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3913 if(SUCCEEDED(hr))
3915 float quad1[] = {
3916 -1.0, -1.0, 0.1, 0.8, 0.2,
3917 -1.0, 0.0, 0.1, 0.8, 0.2,
3918 0.0, -1.0, 0.1, 0.8, 0.2,
3919 0.0, 0.0, 0.1, 0.8, 0.2,
3921 float quad2[] = {
3922 -1.0, 0.0, 0.1, 0.5, 1.0,
3923 -1.0, 1.0, 0.1, 0.5, 1.0,
3924 0.0, 0.0, 0.1, 0.5, 1.0,
3925 0.0, 1.0, 0.1, 0.5, 1.0,
3927 float quad3[] = {
3928 0.0, 0.0, 0.1, 0.5, 1.0,
3929 0.0, 1.0, 0.1, 0.5, 1.0,
3930 1.0, 0.0, 0.1, 0.5, 1.0,
3931 1.0, 1.0, 0.1, 0.5, 1.0,
3933 float quad4[] = {
3934 0.0, -1.0, 0.1, 0.8, 0.2,
3935 0.0, 0.0, 0.1, 0.8, 0.2,
3936 1.0, -1.0, 0.1, 0.8, 0.2,
3937 1.0, 0.0, 0.1, 0.8, 0.2,
3939 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3940 0.0, 0.0, 0.0, 0.0,
3941 0.0, 1.0, 0.0, 0.0,
3942 0.0, 0.0, 0.0, 0.0};
3944 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3946 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3947 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3948 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3949 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3952 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3954 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3955 * it behaves like COUNT2 because normal textures require 2 coords
3957 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3958 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3960 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3962 /* Just to be sure, the same as quad2 above */
3963 memset(mat, 0, sizeof(mat));
3964 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3965 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3966 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3967 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3971 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3972 * used? And what happens to the first?
3974 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3975 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3977 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3979 hr = IDirect3DDevice9_EndScene(device);
3980 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3982 color = getPixelColor(device, 160, 360);
3983 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3984 color = getPixelColor(device, 160, 120);
3985 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3986 color = getPixelColor(device, 480, 120);
3987 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3988 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3989 color = getPixelColor(device, 480, 360);
3990 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3991 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3993 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3995 IDirect3DTexture9_Release(texture);
3997 /* Test projected textures, without any fancy matrices */
3998 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3999 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4000 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4001 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4002 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4003 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4004 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
4005 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4007 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4008 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4009 for(x = 0; x < 4; x++) {
4010 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4012 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4013 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4014 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4015 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4017 hr = IDirect3DDevice9_BeginScene(device);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4019 if(SUCCEEDED(hr))
4021 const float proj_quads[] = {
4022 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4023 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4024 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4025 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4026 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4027 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4028 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4029 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4032 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4033 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
4035 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4037 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
4038 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
4040 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4042 hr = IDirect3DDevice9_EndScene(device);
4043 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4046 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4047 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4048 IDirect3DTexture9_Release(texture);
4050 color = getPixelColor(device, 158, 118);
4051 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
4052 color = getPixelColor(device, 162, 118);
4053 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
4054 color = getPixelColor(device, 158, 122);
4055 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
4056 color = getPixelColor(device, 162, 122);
4057 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
4059 color = getPixelColor(device, 158, 178);
4060 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
4061 color = getPixelColor(device, 162, 178);
4062 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
4063 color = getPixelColor(device, 158, 182);
4064 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
4065 color = getPixelColor(device, 162, 182);
4066 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
4068 color = getPixelColor(device, 318, 118);
4069 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
4070 color = getPixelColor(device, 322, 118);
4071 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
4072 color = getPixelColor(device, 318, 122);
4073 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
4074 color = getPixelColor(device, 322, 122);
4075 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
4077 color = getPixelColor(device, 318, 178);
4078 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
4079 color = getPixelColor(device, 322, 178);
4080 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
4081 color = getPixelColor(device, 318, 182);
4082 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
4083 color = getPixelColor(device, 322, 182);
4084 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
4086 color = getPixelColor(device, 238, 298);
4087 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
4088 color = getPixelColor(device, 242, 298);
4089 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
4090 color = getPixelColor(device, 238, 302);
4091 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
4092 color = getPixelColor(device, 242, 302);
4093 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
4095 color = getPixelColor(device, 238, 388);
4096 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
4097 color = getPixelColor(device, 242, 388);
4098 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4099 color = getPixelColor(device, 238, 392);
4100 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
4101 color = getPixelColor(device, 242, 392);
4102 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
4104 color = getPixelColor(device, 478, 298);
4105 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
4106 color = getPixelColor(device, 482, 298);
4107 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
4108 color = getPixelColor(device, 478, 302);
4109 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
4110 color = getPixelColor(device, 482, 302);
4111 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
4113 color = getPixelColor(device, 478, 388);
4114 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4115 color = getPixelColor(device, 482, 388);
4116 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
4117 color = getPixelColor(device, 478, 392);
4118 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
4119 color = getPixelColor(device, 482, 392);
4120 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
4122 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4123 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4126 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4127 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4128 * Thus watch out if sampling from texels between 0 and 1.
4130 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4131 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4132 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4133 if(!volume) {
4134 skip("Failed to create a volume texture\n");
4135 goto out;
4138 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4139 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4140 for(z = 0; z < 32; z++) {
4141 for(y = 0; y < 32; y++) {
4142 for(x = 0; x < 32; x++) {
4143 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4144 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4145 float r_f = (float) x / 31.0;
4146 float g_f = (float) y / 31.0;
4147 float b_f = (float) z / 31.0;
4149 if(fmt == D3DFMT_A16B16G16R16) {
4150 unsigned short *mem_s = mem;
4151 mem_s[0] = r_f * 65535.0;
4152 mem_s[1] = g_f * 65535.0;
4153 mem_s[2] = b_f * 65535.0;
4154 mem_s[3] = 65535;
4155 } else {
4156 unsigned char *mem_c = mem;
4157 mem_c[0] = b_f * 255.0;
4158 mem_c[1] = g_f * 255.0;
4159 mem_c[2] = r_f * 255.0;
4160 mem_c[3] = 255;
4165 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4166 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4168 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4169 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4171 hr = IDirect3DDevice9_BeginScene(device);
4172 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4173 if(SUCCEEDED(hr))
4175 float quad1[] = {
4176 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4177 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4178 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4179 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4181 float quad2[] = {
4182 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4183 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4184 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4185 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4187 float quad3[] = {
4188 0.0, 0.0, 0.1, 0.0, 0.0,
4189 0.0, 1.0, 0.1, 0.0, 0.0,
4190 1.0, 0.0, 0.1, 0.0, 0.0,
4191 1.0, 1.0, 0.1, 0.0, 0.0
4193 float quad4[] = {
4194 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4195 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4196 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4197 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4199 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4200 0.0, 0.0, 1.0, 0.0,
4201 0.0, 1.0, 0.0, 0.0,
4202 0.0, 0.0, 0.0, 1.0};
4203 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4204 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4206 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4207 * values
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 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4217 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4218 * otherwise the w will be missing(blue).
4219 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4220 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4222 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4223 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4225 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4227 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4228 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4229 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4230 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4231 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4232 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4233 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4235 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4237 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4238 * disable. ATI extends it up to the amount of values needed for the volume texture
4240 memset(mat, 0, sizeof(mat));
4241 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4242 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4243 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4245 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4246 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4248 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4250 hr = IDirect3DDevice9_EndScene(device);
4251 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4254 color = getPixelColor(device, 160, 360);
4255 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4256 color = getPixelColor(device, 160, 120);
4257 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4258 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4259 color = getPixelColor(device, 480, 120);
4260 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4261 color = getPixelColor(device, 480, 360);
4262 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4264 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4265 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4267 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4268 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4269 hr = IDirect3DDevice9_BeginScene(device);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4271 if(SUCCEEDED(hr))
4273 float quad1[] = {
4274 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4275 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4276 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4277 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4279 float quad2[] = {
4280 -1.0, 0.0, 0.1,
4281 -1.0, 1.0, 0.1,
4282 0.0, 0.0, 0.1,
4283 0.0, 1.0, 0.1,
4285 float quad3[] = {
4286 0.0, 0.0, 0.1, 1.0,
4287 0.0, 1.0, 0.1, 1.0,
4288 1.0, 0.0, 0.1, 1.0,
4289 1.0, 1.0, 0.1, 1.0
4291 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4292 0.0, 0.0, 0.0, 0.0,
4293 0.0, 0.0, 0.0, 0.0,
4294 0.0, 1.0, 0.0, 0.0};
4295 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4296 1.0, 0.0, 0.0, 0.0,
4297 0.0, 1.0, 0.0, 0.0,
4298 0.0, 0.0, 1.0, 0.0};
4299 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4300 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4302 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4303 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4304 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4305 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4306 * 4th *input* coordinate.
4308 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4309 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4310 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4311 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4312 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4313 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4315 /* None passed */
4316 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4318 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4319 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4321 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4323 /* 4 used, 1 passed */
4324 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4326 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4327 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4329 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4331 hr = IDirect3DDevice9_EndScene(device);
4332 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4334 color = getPixelColor(device, 160, 360);
4335 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4336 color = getPixelColor(device, 160, 120);
4337 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4338 color = getPixelColor(device, 480, 120);
4339 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4340 /* Quad4: unused */
4342 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4343 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4345 IDirect3DVolumeTexture9_Release(volume);
4347 out:
4348 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4349 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4350 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4351 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4352 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4353 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4354 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4355 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4356 IDirect3DVertexDeclaration9_Release(decl);
4357 IDirect3DVertexDeclaration9_Release(decl2);
4358 IDirect3DVertexDeclaration9_Release(decl3);
4361 static void texdepth_test(IDirect3DDevice9 *device)
4363 IDirect3DPixelShader9 *shader;
4364 HRESULT hr;
4365 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4366 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4367 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4368 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4369 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4370 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4371 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4372 DWORD shader_code[] = {
4373 0xffff0104, /* ps_1_4 */
4374 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4375 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4376 0x0000fffd, /* phase */
4377 0x00000057, 0x800f0005, /* texdepth r5 */
4378 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4379 0x0000ffff /* end */
4381 DWORD color;
4382 float vertex[] = {
4383 -1.0, -1.0, 0.0,
4384 1.0, -1.0, 1.0,
4385 -1.0, 1.0, 0.0,
4386 1.0, 1.0, 1.0
4389 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4395 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4400 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4401 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4403 /* Fill the depth buffer with a gradient */
4404 hr = IDirect3DDevice9_BeginScene(device);
4405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4406 if(SUCCEEDED(hr))
4408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4409 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4410 hr = IDirect3DDevice9_EndScene(device);
4411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4414 /* Now perform the actual tests. Same geometry, but with the shader */
4415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4418 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4419 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4420 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4422 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4423 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4424 hr = IDirect3DDevice9_BeginScene(device);
4425 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4426 if(SUCCEEDED(hr))
4428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4429 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4431 hr = IDirect3DDevice9_EndScene(device);
4432 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4435 color = getPixelColor(device, 158, 240);
4436 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4437 color = getPixelColor(device, 162, 240);
4438 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4440 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4441 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4443 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4444 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4446 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4447 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4448 hr = IDirect3DDevice9_BeginScene(device);
4449 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4450 if(SUCCEEDED(hr))
4452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4453 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4455 hr = IDirect3DDevice9_EndScene(device);
4456 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4459 color = getPixelColor(device, 318, 240);
4460 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4461 color = getPixelColor(device, 322, 240);
4462 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4465 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4468 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4470 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4471 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4472 hr = IDirect3DDevice9_BeginScene(device);
4473 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4474 if(SUCCEEDED(hr))
4476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4477 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4479 hr = IDirect3DDevice9_EndScene(device);
4480 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4483 color = getPixelColor(device, 1, 240);
4484 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4486 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4487 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4489 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4490 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4492 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4493 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4494 hr = IDirect3DDevice9_BeginScene(device);
4495 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4496 if(SUCCEEDED(hr))
4498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4499 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4501 hr = IDirect3DDevice9_EndScene(device);
4502 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4504 color = getPixelColor(device, 318, 240);
4505 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4506 color = getPixelColor(device, 322, 240);
4507 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4509 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4510 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4513 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4515 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4516 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4517 hr = IDirect3DDevice9_BeginScene(device);
4518 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4519 if(SUCCEEDED(hr))
4521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4522 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4524 hr = IDirect3DDevice9_EndScene(device);
4525 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4528 color = getPixelColor(device, 1, 240);
4529 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4531 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4532 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4535 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4537 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4538 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4539 hr = IDirect3DDevice9_BeginScene(device);
4540 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4541 if(SUCCEEDED(hr))
4543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4544 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4546 hr = IDirect3DDevice9_EndScene(device);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4550 color = getPixelColor(device, 638, 240);
4551 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4553 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4554 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4557 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4559 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4561 hr = IDirect3DDevice9_BeginScene(device);
4562 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4563 if(SUCCEEDED(hr))
4565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4566 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4568 hr = IDirect3DDevice9_EndScene(device);
4569 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4572 color = getPixelColor(device, 638, 240);
4573 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4575 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4576 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4578 /* Cleanup */
4579 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4580 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4581 IDirect3DPixelShader9_Release(shader);
4583 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4586 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4589 static void texkill_test(IDirect3DDevice9 *device)
4591 IDirect3DPixelShader9 *shader;
4592 HRESULT hr;
4593 DWORD color;
4595 const float vertex[] = {
4596 /* bottom top right left */
4597 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4598 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4599 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4600 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4603 DWORD shader_code_11[] = {
4604 0xffff0101, /* ps_1_1 */
4605 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4606 0x00000041, 0xb00f0000, /* texkill t0 */
4607 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4608 0x0000ffff /* end */
4610 DWORD shader_code_20[] = {
4611 0xffff0200, /* ps_2_0 */
4612 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4613 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4614 0x01000041, 0xb00f0000, /* texkill t0 */
4615 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4616 0x0000ffff /* end */
4619 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4620 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4621 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4622 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4624 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4625 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4626 hr = IDirect3DDevice9_BeginScene(device);
4627 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4628 if(SUCCEEDED(hr))
4630 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4631 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4633 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4634 hr = IDirect3DDevice9_EndScene(device);
4635 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4637 color = getPixelColor(device, 63, 46);
4638 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4639 color = getPixelColor(device, 66, 46);
4640 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4641 color = getPixelColor(device, 63, 49);
4642 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4643 color = getPixelColor(device, 66, 49);
4644 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4646 color = getPixelColor(device, 578, 46);
4647 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4648 color = getPixelColor(device, 575, 46);
4649 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4650 color = getPixelColor(device, 578, 49);
4651 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4652 color = getPixelColor(device, 575, 49);
4653 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4655 color = getPixelColor(device, 63, 430);
4656 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4657 color = getPixelColor(device, 63, 433);
4658 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4659 color = getPixelColor(device, 66, 433);
4660 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4661 color = getPixelColor(device, 66, 430);
4662 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4664 color = getPixelColor(device, 578, 430);
4665 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4666 color = getPixelColor(device, 578, 433);
4667 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4668 color = getPixelColor(device, 575, 433);
4669 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4670 color = getPixelColor(device, 575, 430);
4671 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4673 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4676 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4678 IDirect3DPixelShader9_Release(shader);
4680 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4681 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4682 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4683 if(FAILED(hr)) {
4684 skip("Failed to create 2.0 test shader, most likely not supported\n");
4685 return;
4688 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4689 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4690 hr = IDirect3DDevice9_BeginScene(device);
4691 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4692 if(SUCCEEDED(hr))
4694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4695 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4696 hr = IDirect3DDevice9_EndScene(device);
4697 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4700 color = getPixelColor(device, 63, 46);
4701 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4702 color = getPixelColor(device, 66, 46);
4703 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4704 color = getPixelColor(device, 63, 49);
4705 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4706 color = getPixelColor(device, 66, 49);
4707 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4709 color = getPixelColor(device, 578, 46);
4710 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4711 color = getPixelColor(device, 575, 46);
4712 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4713 color = getPixelColor(device, 578, 49);
4714 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4715 color = getPixelColor(device, 575, 49);
4716 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4718 color = getPixelColor(device, 63, 430);
4719 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4720 color = getPixelColor(device, 63, 433);
4721 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4722 color = getPixelColor(device, 66, 433);
4723 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4724 color = getPixelColor(device, 66, 430);
4725 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4727 color = getPixelColor(device, 578, 430);
4728 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4729 color = getPixelColor(device, 578, 433);
4730 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4731 color = getPixelColor(device, 575, 433);
4732 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4733 color = getPixelColor(device, 575, 430);
4734 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4736 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4737 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4739 /* Cleanup */
4740 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4741 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4742 IDirect3DPixelShader9_Release(shader);
4745 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4747 IDirect3D9 *d3d9;
4748 HRESULT hr;
4749 IDirect3DTexture9 *texture;
4750 IDirect3DPixelShader9 *shader;
4751 IDirect3DPixelShader9 *shader2;
4752 D3DLOCKED_RECT lr;
4753 DWORD color;
4754 DWORD shader_code[] = {
4755 0xffff0101, /* ps_1_1 */
4756 0x00000042, 0xb00f0000, /* tex t0 */
4757 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4758 0x0000ffff /* end */
4760 DWORD shader_code2[] = {
4761 0xffff0101, /* ps_1_1 */
4762 0x00000042, 0xb00f0000, /* tex t0 */
4763 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4764 0x0000ffff /* end */
4767 float quad[] = {
4768 -1.0, -1.0, 0.1, 0.5, 0.5,
4769 1.0, -1.0, 0.1, 0.5, 0.5,
4770 -1.0, 1.0, 0.1, 0.5, 0.5,
4771 1.0, 1.0, 0.1, 0.5, 0.5,
4774 memset(&lr, 0, sizeof(lr));
4775 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4776 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4777 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4778 IDirect3D9_Release(d3d9);
4779 if(FAILED(hr)) {
4780 skip("No D3DFMT_X8L8V8U8 support\n");
4781 return;
4784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4785 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4787 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4789 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4790 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4791 *((DWORD *) lr.pBits) = 0x11ca3141;
4792 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4793 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4795 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4797 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4800 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4802 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4803 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4804 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4807 hr = IDirect3DDevice9_BeginScene(device);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4809 if(SUCCEEDED(hr))
4811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4812 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4814 hr = IDirect3DDevice9_EndScene(device);
4815 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4817 color = getPixelColor(device, 578, 430);
4818 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4819 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4821 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4823 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4825 hr = IDirect3DDevice9_BeginScene(device);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4827 if(SUCCEEDED(hr))
4829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4830 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4832 hr = IDirect3DDevice9_EndScene(device);
4833 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4835 color = getPixelColor(device, 578, 430);
4836 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4837 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4840 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4841 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4842 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4843 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4844 IDirect3DPixelShader9_Release(shader);
4845 IDirect3DPixelShader9_Release(shader2);
4846 IDirect3DTexture9_Release(texture);
4849 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4851 HRESULT hr;
4852 IDirect3D9 *d3d;
4853 IDirect3DTexture9 *texture = NULL;
4854 IDirect3DSurface9 *surface;
4855 DWORD color;
4856 const RECT r1 = {256, 256, 512, 512};
4857 const RECT r2 = {512, 256, 768, 512};
4858 const RECT r3 = {256, 512, 512, 768};
4859 const RECT r4 = {512, 512, 768, 768};
4860 unsigned int x, y;
4861 D3DLOCKED_RECT lr;
4862 memset(&lr, 0, sizeof(lr));
4864 IDirect3DDevice9_GetDirect3D(device, &d3d);
4865 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4866 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4867 skip("No autogenmipmap support\n");
4868 IDirect3D9_Release(d3d);
4869 return;
4871 IDirect3D9_Release(d3d);
4873 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4874 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4876 /* Make the mipmap big, so that a smaller mipmap is used
4878 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4879 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4880 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4882 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4883 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4884 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4885 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4886 for(y = 0; y < 1024; y++) {
4887 for(x = 0; x < 1024; x++) {
4888 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4889 POINT pt;
4891 pt.x = x;
4892 pt.y = y;
4893 if(PtInRect(&r1, pt)) {
4894 *dst = 0xffff0000;
4895 } else if(PtInRect(&r2, pt)) {
4896 *dst = 0xff00ff00;
4897 } else if(PtInRect(&r3, pt)) {
4898 *dst = 0xff0000ff;
4899 } else if(PtInRect(&r4, pt)) {
4900 *dst = 0xff000000;
4901 } else {
4902 *dst = 0xffffffff;
4906 hr = IDirect3DSurface9_UnlockRect(surface);
4907 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4908 IDirect3DSurface9_Release(surface);
4910 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4911 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4912 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4913 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4915 hr = IDirect3DDevice9_BeginScene(device);
4916 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4917 if(SUCCEEDED(hr)) {
4918 const float quad[] = {
4919 -0.5, -0.5, 0.1, 0.0, 0.0,
4920 -0.5, 0.5, 0.1, 0.0, 1.0,
4921 0.5, -0.5, 0.1, 1.0, 0.0,
4922 0.5, 0.5, 0.1, 1.0, 1.0
4925 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4926 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4928 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4929 hr = IDirect3DDevice9_EndScene(device);
4930 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4932 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4933 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4934 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4935 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4936 IDirect3DTexture9_Release(texture);
4938 color = getPixelColor(device, 200, 200);
4939 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4940 color = getPixelColor(device, 280, 200);
4941 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4942 color = getPixelColor(device, 360, 200);
4943 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4944 color = getPixelColor(device, 440, 200);
4945 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4946 color = getPixelColor(device, 200, 270);
4947 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4948 color = getPixelColor(device, 280, 270);
4949 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4950 color = getPixelColor(device, 360, 270);
4951 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4952 color = getPixelColor(device, 440, 270);
4953 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4954 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4958 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4960 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4961 IDirect3DVertexDeclaration9 *decl;
4962 HRESULT hr;
4963 DWORD color;
4964 DWORD shader_code_11[] = {
4965 0xfffe0101, /* vs_1_1 */
4966 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4967 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4968 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4969 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4970 0x0000ffff /* end */
4972 DWORD shader_code_11_2[] = {
4973 0xfffe0101, /* vs_1_1 */
4974 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4975 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4976 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4977 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4978 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4979 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4980 0x0000ffff /* end */
4982 DWORD shader_code_20[] = {
4983 0xfffe0200, /* vs_2_0 */
4984 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4985 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4986 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4987 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4988 0x0000ffff /* end */
4990 DWORD shader_code_20_2[] = {
4991 0xfffe0200, /* vs_2_0 */
4992 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4993 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4994 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4995 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4996 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4997 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4998 0x0000ffff /* end */
5000 static const D3DVERTEXELEMENT9 decl_elements[] = {
5001 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5002 D3DDECL_END()
5004 float quad1[] = {
5005 -1.0, -1.0, 0.1,
5006 0.0, -1.0, 0.1,
5007 -1.0, 0.0, 0.1,
5008 0.0, 0.0, 0.1
5010 float quad2[] = {
5011 0.0, -1.0, 0.1,
5012 1.0, -1.0, 0.1,
5013 0.0, 0.0, 0.1,
5014 1.0, 0.0, 0.1
5016 float quad3[] = {
5017 0.0, 0.0, 0.1,
5018 1.0, 0.0, 0.1,
5019 0.0, 1.0, 0.1,
5020 1.0, 1.0, 0.1
5022 float quad4[] = {
5023 -1.0, 0.0, 0.1,
5024 0.0, 0.0, 0.1,
5025 -1.0, 1.0, 0.1,
5026 0.0, 1.0, 0.1
5028 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5029 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5034 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5036 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5038 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5039 if(FAILED(hr)) shader_20 = NULL;
5040 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5041 if(FAILED(hr)) shader_20_2 = NULL;
5042 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5043 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5045 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5046 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5047 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5048 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5049 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5050 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5052 hr = IDirect3DDevice9_BeginScene(device);
5053 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5054 if(SUCCEEDED(hr))
5056 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5059 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5061 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5062 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5064 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5066 if(shader_20) {
5067 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5068 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5070 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5073 if(shader_20_2) {
5074 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5075 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5076 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5077 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5080 hr = IDirect3DDevice9_EndScene(device);
5081 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5084 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5085 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5086 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5089 color = getPixelColor(device, 160, 360);
5090 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5091 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5092 color = getPixelColor(device, 480, 360);
5093 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5094 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5095 if(shader_20) {
5096 color = getPixelColor(device, 480, 120);
5097 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5098 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5100 if(shader_20_2) {
5101 color = getPixelColor(device, 160, 120);
5102 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5103 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5106 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5108 IDirect3DVertexDeclaration9_Release(decl);
5109 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5110 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5111 IDirect3DVertexShader9_Release(shader_11_2);
5112 IDirect3DVertexShader9_Release(shader_11);
5115 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5117 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5118 HRESULT hr;
5119 DWORD color;
5120 DWORD shader_code_11[] = {
5121 0xffff0101, /* ps_1_1 */
5122 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5123 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5124 0x0000ffff /* end */
5126 DWORD shader_code_12[] = {
5127 0xffff0102, /* ps_1_2 */
5128 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5129 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5130 0x0000ffff /* end */
5132 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5133 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5134 * During development of this test, 1.3 shaders were verified too
5136 DWORD shader_code_14[] = {
5137 0xffff0104, /* ps_1_4 */
5138 /* Try to make one constant local. It gets clamped too, although the binary contains
5139 * the bigger numbers
5141 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5142 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5143 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5144 0x0000ffff /* end */
5146 DWORD shader_code_20[] = {
5147 0xffff0200, /* ps_2_0 */
5148 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5149 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5150 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5151 0x0000ffff /* end */
5153 float quad1[] = {
5154 -1.0, -1.0, 0.1,
5155 0.0, -1.0, 0.1,
5156 -1.0, 0.0, 0.1,
5157 0.0, 0.0, 0.1
5159 float quad2[] = {
5160 0.0, -1.0, 0.1,
5161 1.0, -1.0, 0.1,
5162 0.0, 0.0, 0.1,
5163 1.0, 0.0, 0.1
5165 float quad3[] = {
5166 0.0, 0.0, 0.1,
5167 1.0, 0.0, 0.1,
5168 0.0, 1.0, 0.1,
5169 1.0, 1.0, 0.1
5171 float quad4[] = {
5172 -1.0, 0.0, 0.1,
5173 0.0, 0.0, 0.1,
5174 -1.0, 1.0, 0.1,
5175 0.0, 1.0, 0.1
5177 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5178 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5180 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5181 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5183 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5184 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5185 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5186 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5187 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5188 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5189 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5190 if(FAILED(hr)) shader_20 = NULL;
5192 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5194 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5195 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5196 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5197 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5199 hr = IDirect3DDevice9_BeginScene(device);
5200 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5201 if(SUCCEEDED(hr))
5203 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5204 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5206 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5208 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5209 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5211 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5213 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5214 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5216 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5218 if(shader_20) {
5219 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5220 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5221 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5222 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5225 hr = IDirect3DDevice9_EndScene(device);
5226 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5228 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5231 color = getPixelColor(device, 160, 360);
5232 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5233 "quad 1 has color %08x, expected 0x00808000\n", color);
5234 color = getPixelColor(device, 480, 360);
5235 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5236 "quad 2 has color %08x, expected 0x00808000\n", color);
5237 color = getPixelColor(device, 480, 120);
5238 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5239 "quad 3 has color %08x, expected 0x00808000\n", color);
5240 if(shader_20) {
5241 color = getPixelColor(device, 160, 120);
5242 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5243 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5245 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5246 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5248 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5249 IDirect3DPixelShader9_Release(shader_14);
5250 IDirect3DPixelShader9_Release(shader_12);
5251 IDirect3DPixelShader9_Release(shader_11);
5254 static void dp2add_ps_test(IDirect3DDevice9 *device)
5256 IDirect3DPixelShader9 *shader_dp2add = NULL;
5257 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5258 HRESULT hr;
5259 DWORD color;
5261 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5262 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5263 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5264 * r0 first.
5265 * The result here for the r,g,b components should be roughly 0.5:
5266 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5267 static const DWORD shader_code_dp2add[] = {
5268 0xffff0200, /* ps_2_0 */
5269 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5271 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5272 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5274 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5275 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5276 0x0000ffff /* end */
5279 /* Test the _sat modifier, too. Result here should be:
5280 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5281 * _SAT: ==> 1.0
5282 * ADD: (1.0 + -0.5) = 0.5
5284 static const DWORD shader_code_dp2add_sat[] = {
5285 0xffff0200, /* ps_2_0 */
5286 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5288 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5289 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5290 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5292 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5293 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5294 0x0000ffff /* end */
5297 const float quad[] = {
5298 -1.0, -1.0, 0.1,
5299 1.0, -1.0, 0.1,
5300 -1.0, 1.0, 0.1,
5301 1.0, 1.0, 0.1
5305 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5308 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5309 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5311 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5312 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5314 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5315 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5317 if (shader_dp2add) {
5319 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5322 hr = IDirect3DDevice9_BeginScene(device);
5323 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5324 if(SUCCEEDED(hr))
5326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5327 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5329 hr = IDirect3DDevice9_EndScene(device);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5333 color = getPixelColor(device, 360, 240);
5334 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5335 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5340 IDirect3DPixelShader9_Release(shader_dp2add);
5341 } else {
5342 skip("dp2add shader creation failed\n");
5345 if (shader_dp2add_sat) {
5347 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5350 hr = IDirect3DDevice9_BeginScene(device);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5352 if(SUCCEEDED(hr))
5354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5355 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5357 hr = IDirect3DDevice9_EndScene(device);
5358 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5361 color = getPixelColor(device, 360, 240);
5362 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5363 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5366 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5368 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5369 } else {
5370 skip("dp2add shader creation failed\n");
5373 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5374 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5377 static void cnd_test(IDirect3DDevice9 *device)
5379 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5380 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5381 HRESULT hr;
5382 DWORD color;
5383 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5384 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5385 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5387 DWORD shader_code_11[] = {
5388 0xffff0101, /* ps_1_1 */
5389 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5390 0x00000040, 0xb00f0000, /* texcoord t0 */
5391 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5392 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5393 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5394 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5395 0x0000ffff /* end */
5397 DWORD shader_code_12[] = {
5398 0xffff0102, /* ps_1_2 */
5399 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5400 0x00000040, 0xb00f0000, /* texcoord t0 */
5401 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5402 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5403 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5404 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5405 0x0000ffff /* end */
5407 DWORD shader_code_13[] = {
5408 0xffff0103, /* ps_1_3 */
5409 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5410 0x00000040, 0xb00f0000, /* texcoord t0 */
5411 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5412 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5413 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5414 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5415 0x0000ffff /* end */
5417 DWORD shader_code_14[] = {
5418 0xffff0104, /* ps_1_3 */
5419 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5420 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5421 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5422 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5423 0x0000ffff /* end */
5426 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5427 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5428 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5429 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5430 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5431 * well enough.
5433 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5434 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5435 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5436 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5438 DWORD shader_code_11_coissue[] = {
5439 0xffff0101, /* ps_1_1 */
5440 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5441 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5442 0x00000040, 0xb00f0000, /* texcoord t0 */
5443 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5444 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5445 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5446 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5447 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5448 /* 0x40000000 = D3DSI_COISSUE */
5449 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5450 0x0000ffff /* end */
5452 DWORD shader_code_12_coissue[] = {
5453 0xffff0102, /* ps_1_2 */
5454 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5455 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5456 0x00000040, 0xb00f0000, /* texcoord t0 */
5457 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5458 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5459 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5460 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5461 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5462 /* 0x40000000 = D3DSI_COISSUE */
5463 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5464 0x0000ffff /* end */
5466 DWORD shader_code_13_coissue[] = {
5467 0xffff0103, /* ps_1_3 */
5468 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5469 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5470 0x00000040, 0xb00f0000, /* texcoord t0 */
5471 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5472 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5473 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5474 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5475 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5476 /* 0x40000000 = D3DSI_COISSUE */
5477 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5478 0x0000ffff /* end */
5480 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5481 * compare against 0.5
5483 DWORD shader_code_14_coissue[] = {
5484 0xffff0104, /* ps_1_4 */
5485 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5486 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5487 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5488 /* 0x40000000 = D3DSI_COISSUE */
5489 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5490 0x0000ffff /* end */
5492 float quad1[] = {
5493 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5494 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5495 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5496 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5498 float quad2[] = {
5499 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5500 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5501 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5502 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5504 float quad3[] = {
5505 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5506 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5507 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5508 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5510 float quad4[] = {
5511 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5512 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5513 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5514 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5516 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5517 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5518 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5519 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5521 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5524 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5526 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5528 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5529 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5530 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5532 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5533 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5534 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5535 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5536 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5537 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5538 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5539 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5541 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5543 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5544 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5545 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5548 hr = IDirect3DDevice9_BeginScene(device);
5549 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5550 if(SUCCEEDED(hr))
5552 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5553 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5555 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5557 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5558 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5559 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5560 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5562 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5563 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5564 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5565 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5567 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5568 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5569 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5570 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5572 hr = IDirect3DDevice9_EndScene(device);
5573 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5576 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5577 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5579 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5580 color = getPixelColor(device, 158, 118);
5581 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5582 color = getPixelColor(device, 162, 118);
5583 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5584 color = getPixelColor(device, 158, 122);
5585 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5586 color = getPixelColor(device, 162, 122);
5587 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5589 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5590 color = getPixelColor(device, 158, 358);
5591 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5592 color = getPixelColor(device, 162, 358);
5593 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5594 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5595 color = getPixelColor(device, 158, 362);
5596 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5597 color = getPixelColor(device, 162, 362);
5598 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5599 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5601 /* 1.2 shader */
5602 color = getPixelColor(device, 478, 358);
5603 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5604 color = getPixelColor(device, 482, 358);
5605 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5606 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5607 color = getPixelColor(device, 478, 362);
5608 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5609 color = getPixelColor(device, 482, 362);
5610 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5611 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5613 /* 1.3 shader */
5614 color = getPixelColor(device, 478, 118);
5615 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5616 color = getPixelColor(device, 482, 118);
5617 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5618 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5619 color = getPixelColor(device, 478, 122);
5620 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5621 color = getPixelColor(device, 482, 122);
5622 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5623 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5626 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5629 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5630 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5631 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5632 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5635 hr = IDirect3DDevice9_BeginScene(device);
5636 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5637 if(SUCCEEDED(hr))
5639 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5640 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5642 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5644 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5645 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5647 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5649 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5650 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5652 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5654 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5655 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5657 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5659 hr = IDirect3DDevice9_EndScene(device);
5660 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5663 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5664 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5666 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5667 * that we swapped the values in c1 and c2 to make the other tests return some color
5669 color = getPixelColor(device, 158, 118);
5670 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5671 color = getPixelColor(device, 162, 118);
5672 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5673 color = getPixelColor(device, 158, 122);
5674 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5675 color = getPixelColor(device, 162, 122);
5676 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5678 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5679 * (The Win7 nvidia driver always selects c2)
5681 color = getPixelColor(device, 158, 358);
5682 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5683 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5684 color = getPixelColor(device, 162, 358);
5685 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5686 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5687 color = getPixelColor(device, 158, 362);
5688 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5689 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5690 color = getPixelColor(device, 162, 362);
5691 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5692 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5694 /* 1.2 shader */
5695 color = getPixelColor(device, 478, 358);
5696 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5697 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5698 color = getPixelColor(device, 482, 358);
5699 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5700 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5701 color = getPixelColor(device, 478, 362);
5702 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5703 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5704 color = getPixelColor(device, 482, 362);
5705 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5706 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5708 /* 1.3 shader */
5709 color = getPixelColor(device, 478, 118);
5710 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5711 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5712 color = getPixelColor(device, 482, 118);
5713 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5714 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5715 color = getPixelColor(device, 478, 122);
5716 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5717 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5718 color = getPixelColor(device, 482, 122);
5719 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5720 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5722 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5723 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5725 IDirect3DPixelShader9_Release(shader_14_coissue);
5726 IDirect3DPixelShader9_Release(shader_13_coissue);
5727 IDirect3DPixelShader9_Release(shader_12_coissue);
5728 IDirect3DPixelShader9_Release(shader_11_coissue);
5729 IDirect3DPixelShader9_Release(shader_14);
5730 IDirect3DPixelShader9_Release(shader_13);
5731 IDirect3DPixelShader9_Release(shader_12);
5732 IDirect3DPixelShader9_Release(shader_11);
5735 static void nested_loop_test(IDirect3DDevice9 *device) {
5736 const DWORD shader_code[] = {
5737 0xffff0300, /* ps_3_0 */
5738 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5739 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5740 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5741 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5742 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5743 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5744 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5745 0x0000001d, /* endloop */
5746 0x0000001d, /* endloop */
5747 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5748 0x0000ffff /* end */
5750 const DWORD vshader_code[] = {
5751 0xfffe0300, /* vs_3_0 */
5752 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5753 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5754 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5755 0x0000ffff /* end */
5757 IDirect3DPixelShader9 *shader;
5758 IDirect3DVertexShader9 *vshader;
5759 HRESULT hr;
5760 DWORD color;
5761 const float quad[] = {
5762 -1.0, -1.0, 0.1,
5763 1.0, -1.0, 0.1,
5764 -1.0, 1.0, 0.1,
5765 1.0, 1.0, 0.1
5768 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5770 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5771 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5772 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5774 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5778 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5781 hr = IDirect3DDevice9_BeginScene(device);
5782 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5783 if(SUCCEEDED(hr))
5785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5786 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5787 hr = IDirect3DDevice9_EndScene(device);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5791 color = getPixelColor(device, 360, 240);
5792 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5793 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5796 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5798 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5800 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5801 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5802 IDirect3DPixelShader9_Release(shader);
5803 IDirect3DVertexShader9_Release(vshader);
5806 struct varying_test_struct
5808 const DWORD *shader_code;
5809 IDirect3DPixelShader9 *shader;
5810 DWORD color, color_rhw;
5811 const char *name;
5812 BOOL todo, todo_rhw;
5815 struct hugeVertex
5817 float pos_x, pos_y, pos_z, rhw;
5818 float weight_1, weight_2, weight_3, weight_4;
5819 float index_1, index_2, index_3, index_4;
5820 float normal_1, normal_2, normal_3, normal_4;
5821 float fog_1, fog_2, fog_3, fog_4;
5822 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5823 float tangent_1, tangent_2, tangent_3, tangent_4;
5824 float binormal_1, binormal_2, binormal_3, binormal_4;
5825 float depth_1, depth_2, depth_3, depth_4;
5826 DWORD diffuse, specular;
5829 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5830 /* dcl_position: fails to compile */
5831 const DWORD blendweight_code[] = {
5832 0xffff0300, /* ps_3_0 */
5833 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5834 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5835 0x0000ffff /* end */
5837 const DWORD blendindices_code[] = {
5838 0xffff0300, /* ps_3_0 */
5839 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5840 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5841 0x0000ffff /* end */
5843 const DWORD normal_code[] = {
5844 0xffff0300, /* ps_3_0 */
5845 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5846 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5847 0x0000ffff /* end */
5849 /* psize: fails? */
5850 const DWORD texcoord0_code[] = {
5851 0xffff0300, /* ps_3_0 */
5852 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5853 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5854 0x0000ffff /* end */
5856 const DWORD tangent_code[] = {
5857 0xffff0300, /* ps_3_0 */
5858 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5859 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5860 0x0000ffff /* end */
5862 const DWORD binormal_code[] = {
5863 0xffff0300, /* ps_3_0 */
5864 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5865 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5866 0x0000ffff /* end */
5868 /* tessfactor: fails */
5869 /* positiont: fails */
5870 const DWORD color_code[] = {
5871 0xffff0300, /* ps_3_0 */
5872 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5873 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5874 0x0000ffff /* end */
5876 const DWORD fog_code[] = {
5877 0xffff0300, /* ps_3_0 */
5878 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5879 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5880 0x0000ffff /* end */
5882 const DWORD depth_code[] = {
5883 0xffff0300, /* ps_3_0 */
5884 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5885 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5886 0x0000ffff /* end */
5888 const DWORD specular_code[] = {
5889 0xffff0300, /* ps_3_0 */
5890 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5891 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5892 0x0000ffff /* end */
5894 /* sample: fails */
5896 struct varying_test_struct tests[] = {
5897 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5898 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5899 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5900 /* Why does dx not forward the texcoord? */
5901 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5902 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5903 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5904 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5905 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5906 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5907 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5909 /* Declare a monster vertex type :-) */
5910 static const D3DVERTEXELEMENT9 decl_elements[] = {
5911 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5912 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5913 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5914 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5915 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5916 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5917 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5918 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5919 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5920 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5921 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5922 D3DDECL_END()
5924 struct hugeVertex data[4] = {
5926 -1.0, -1.0, 0.1, 1.0,
5927 0.1, 0.1, 0.1, 0.1,
5928 0.2, 0.2, 0.2, 0.2,
5929 0.3, 0.3, 0.3, 0.3,
5930 0.4, 0.4, 0.4, 0.4,
5931 0.50, 0.55, 0.55, 0.55,
5932 0.6, 0.6, 0.6, 0.7,
5933 0.7, 0.7, 0.7, 0.6,
5934 0.8, 0.8, 0.8, 0.8,
5935 0xe6e6e6e6, /* 0.9 * 256 */
5936 0x224488ff /* Nothing special */
5939 1.0, -1.0, 0.1, 1.0,
5940 0.1, 0.1, 0.1, 0.1,
5941 0.2, 0.2, 0.2, 0.2,
5942 0.3, 0.3, 0.3, 0.3,
5943 0.4, 0.4, 0.4, 0.4,
5944 0.50, 0.55, 0.55, 0.55,
5945 0.6, 0.6, 0.6, 0.7,
5946 0.7, 0.7, 0.7, 0.6,
5947 0.8, 0.8, 0.8, 0.8,
5948 0xe6e6e6e6, /* 0.9 * 256 */
5949 0x224488ff /* Nothing special */
5952 -1.0, 1.0, 0.1, 1.0,
5953 0.1, 0.1, 0.1, 0.1,
5954 0.2, 0.2, 0.2, 0.2,
5955 0.3, 0.3, 0.3, 0.3,
5956 0.4, 0.4, 0.4, 0.4,
5957 0.50, 0.55, 0.55, 0.55,
5958 0.6, 0.6, 0.6, 0.7,
5959 0.7, 0.7, 0.7, 0.6,
5960 0.8, 0.8, 0.8, 0.8,
5961 0xe6e6e6e6, /* 0.9 * 256 */
5962 0x224488ff /* Nothing special */
5965 1.0, 1.0, 0.1, 1.0,
5966 0.1, 0.1, 0.1, 0.1,
5967 0.2, 0.2, 0.2, 0.2,
5968 0.3, 0.3, 0.3, 0.3,
5969 0.4, 0.4, 0.4, 0.4,
5970 0.50, 0.55, 0.55, 0.55,
5971 0.6, 0.6, 0.6, 0.7,
5972 0.7, 0.7, 0.7, 0.6,
5973 0.8, 0.8, 0.8, 0.8,
5974 0xe6e6e6e6, /* 0.9 * 256 */
5975 0x224488ff /* Nothing special */
5978 struct hugeVertex data2[4];
5979 IDirect3DVertexDeclaration9 *decl;
5980 HRESULT hr;
5981 unsigned int i;
5982 DWORD color, r, g, b, r_e, g_e, b_e;
5984 memcpy(data2, data, sizeof(data2));
5985 data2[0].pos_x = 0; data2[0].pos_y = 0;
5986 data2[1].pos_x = 640; data2[1].pos_y = 0;
5987 data2[2].pos_x = 0; data2[2].pos_y = 480;
5988 data2[3].pos_x = 640; data2[3].pos_y = 480;
5990 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5991 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5992 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5993 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5995 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5997 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5998 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5999 tests[i].name, hr);
6002 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6003 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6004 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6006 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6007 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6009 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6010 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6012 hr = IDirect3DDevice9_BeginScene(device);
6013 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6014 if(SUCCEEDED(hr))
6016 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6017 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6018 hr = IDirect3DDevice9_EndScene(device);
6019 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6022 color = getPixelColor(device, 360, 240);
6023 r = color & 0x00ff0000 >> 16;
6024 g = color & 0x0000ff00 >> 8;
6025 b = color & 0x000000ff;
6026 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6027 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
6028 b_e = tests[i].color_rhw & 0x000000ff;
6030 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6031 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6033 if(tests[i].todo_rhw) {
6034 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6035 * pipeline
6037 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6038 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6039 tests[i].name, color, tests[i].color_rhw);
6040 } else {
6041 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6042 "Test %s returned color 0x%08x, expected 0x%08x\n",
6043 tests[i].name, color, tests[i].color_rhw);
6047 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6049 IDirect3DPixelShader9_Release(tests[i].shader);
6052 IDirect3DVertexDeclaration9_Release(decl);
6055 static void test_compare_instructions(IDirect3DDevice9 *device)
6057 DWORD shader_sge_vec_code[] = {
6058 0xfffe0101, /* vs_1_1 */
6059 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6060 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6061 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6062 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6063 0x0000ffff /* end */
6065 DWORD shader_slt_vec_code[] = {
6066 0xfffe0101, /* vs_1_1 */
6067 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6068 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6069 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6070 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6071 0x0000ffff /* end */
6073 DWORD shader_sge_scalar_code[] = {
6074 0xfffe0101, /* vs_1_1 */
6075 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6076 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6077 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6078 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6079 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6080 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6081 0x0000ffff /* end */
6083 DWORD shader_slt_scalar_code[] = {
6084 0xfffe0101, /* vs_1_1 */
6085 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6086 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6087 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6088 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6089 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6090 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6091 0x0000ffff /* end */
6093 IDirect3DVertexShader9 *shader_sge_vec;
6094 IDirect3DVertexShader9 *shader_slt_vec;
6095 IDirect3DVertexShader9 *shader_sge_scalar;
6096 IDirect3DVertexShader9 *shader_slt_scalar;
6097 HRESULT hr, color;
6098 float quad1[] = {
6099 -1.0, -1.0, 0.1,
6100 0.0, -1.0, 0.1,
6101 -1.0, 0.0, 0.1,
6102 0.0, 0.0, 0.1
6104 float quad2[] = {
6105 0.0, -1.0, 0.1,
6106 1.0, -1.0, 0.1,
6107 0.0, 0.0, 0.1,
6108 1.0, 0.0, 0.1
6110 float quad3[] = {
6111 -1.0, 0.0, 0.1,
6112 0.0, 0.0, 0.1,
6113 -1.0, 1.0, 0.1,
6114 0.0, 1.0, 0.1
6116 float quad4[] = {
6117 0.0, 0.0, 0.1,
6118 1.0, 0.0, 0.1,
6119 0.0, 1.0, 0.1,
6120 1.0, 1.0, 0.1
6122 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6123 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6126 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6128 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6129 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6130 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6131 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6132 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6133 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6134 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6135 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6136 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6137 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6138 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6139 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6140 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6141 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6143 hr = IDirect3DDevice9_BeginScene(device);
6144 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6145 if(SUCCEEDED(hr))
6147 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6148 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6150 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6152 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6153 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6155 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6157 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6158 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6160 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6162 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6163 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6165 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6166 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6167 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6168 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6170 hr = IDirect3DDevice9_EndScene(device);
6171 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6174 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6175 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6177 color = getPixelColor(device, 160, 360);
6178 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6179 color = getPixelColor(device, 480, 360);
6180 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6181 color = getPixelColor(device, 160, 120);
6182 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6183 color = getPixelColor(device, 480, 160);
6184 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6186 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6187 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6189 IDirect3DVertexShader9_Release(shader_sge_vec);
6190 IDirect3DVertexShader9_Release(shader_slt_vec);
6191 IDirect3DVertexShader9_Release(shader_sge_scalar);
6192 IDirect3DVertexShader9_Release(shader_slt_scalar);
6195 static void test_vshader_input(IDirect3DDevice9 *device)
6197 static const DWORD swapped_shader_code_3[] =
6199 0xfffe0300, /* vs_3_0 */
6200 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6201 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6202 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6203 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6204 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6205 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6206 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6207 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6208 0x0000ffff /* end */
6210 static const DWORD swapped_shader_code_1[] =
6212 0xfffe0101, /* vs_1_1 */
6213 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6214 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6215 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6216 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6217 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6218 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6219 0x0000ffff /* end */
6221 static const DWORD swapped_shader_code_2[] =
6223 0xfffe0200, /* vs_2_0 */
6224 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6225 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6226 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6227 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6228 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6229 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6230 0x0000ffff /* end */
6232 static const DWORD texcoord_color_shader_code_3[] =
6234 0xfffe0300, /* vs_3_0 */
6235 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6236 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6237 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6238 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6239 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6240 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6241 0x0000ffff /* end */
6243 static const DWORD texcoord_color_shader_code_2[] =
6245 0xfffe0200, /* vs_2_0 */
6246 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6247 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6248 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6249 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6250 0x0000ffff /* end */
6252 static const DWORD texcoord_color_shader_code_1[] =
6254 0xfffe0101, /* vs_1_1 */
6255 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6256 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6257 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6258 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6259 0x0000ffff /* end */
6261 static const DWORD color_color_shader_code_3[] =
6263 0xfffe0300, /* vs_3_0 */
6264 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6265 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6266 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6267 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6268 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6269 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6270 0x0000ffff /* end */
6272 static const DWORD color_color_shader_code_2[] =
6274 0xfffe0200, /* vs_2_0 */
6275 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6276 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6277 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6278 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6279 0x0000ffff /* end */
6281 static const DWORD color_color_shader_code_1[] =
6283 0xfffe0101, /* vs_1_1 */
6284 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6285 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6286 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6287 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6288 0x0000ffff /* end */
6290 static const DWORD ps3_code[] =
6292 0xffff0300, /* ps_3_0 */
6293 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6294 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6295 0x0000ffff /* end */
6297 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6298 IDirect3DPixelShader9 *ps;
6299 HRESULT hr;
6300 DWORD color;
6301 float quad1[] = {
6302 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6303 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6304 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6305 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6307 float quad2[] = {
6308 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6309 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6310 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6311 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6313 float quad3[] = {
6314 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6315 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6316 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6317 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6319 float quad4[] = {
6320 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6321 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6322 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6323 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6325 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6326 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6327 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6328 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6329 D3DDECL_END()
6331 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6332 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6333 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6334 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6335 D3DDECL_END()
6337 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6338 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6339 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6340 D3DDECL_END()
6342 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6343 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6344 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6345 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6346 D3DDECL_END()
6348 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6349 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6350 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6351 D3DDECL_END()
6353 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6354 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6355 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6356 D3DDECL_END()
6358 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6359 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6360 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6361 D3DDECL_END()
6363 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6364 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6365 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6366 D3DDECL_END()
6368 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6369 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6370 unsigned int i;
6371 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6372 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6374 struct vertex quad1_color[] = {
6375 {-1.0, -1.0, 0.1, 0x00ff8040},
6376 { 0.0, -1.0, 0.1, 0x00ff8040},
6377 {-1.0, 0.0, 0.1, 0x00ff8040},
6378 { 0.0, 0.0, 0.1, 0x00ff8040}
6380 struct vertex quad2_color[] = {
6381 { 0.0, -1.0, 0.1, 0x00ff8040},
6382 { 1.0, -1.0, 0.1, 0x00ff8040},
6383 { 0.0, 0.0, 0.1, 0x00ff8040},
6384 { 1.0, 0.0, 0.1, 0x00ff8040}
6386 struct vertex quad3_color[] = {
6387 {-1.0, 0.0, 0.1, 0x00ff8040},
6388 { 0.0, 0.0, 0.1, 0x00ff8040},
6389 {-1.0, 1.0, 0.1, 0x00ff8040},
6390 { 0.0, 1.0, 0.1, 0x00ff8040}
6392 float quad4_color[] = {
6393 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6394 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6395 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6396 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6399 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6400 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6401 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6403 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6404 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6405 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6408 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6409 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6410 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6412 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6413 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6414 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6415 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6417 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6420 for(i = 1; i <= 3; i++) {
6421 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6422 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6423 if(i == 3) {
6424 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6425 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6426 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6427 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6428 } else if(i == 2){
6429 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6430 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6431 } else if(i == 1) {
6432 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6436 hr = IDirect3DDevice9_BeginScene(device);
6437 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6438 if(SUCCEEDED(hr))
6440 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6441 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6443 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6444 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6446 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6448 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6449 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6450 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6451 if(i == 3 || i == 2) {
6452 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6453 } else if(i == 1) {
6454 /* Succeeds or fails, depending on SW or HW vertex processing */
6455 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6458 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6459 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6461 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6463 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6464 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6466 if(i == 3 || i == 2) {
6467 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6468 } else if(i == 1) {
6469 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6472 hr = IDirect3DDevice9_EndScene(device);
6473 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6476 if(i == 3 || i == 2) {
6477 color = getPixelColor(device, 160, 360);
6478 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6479 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6481 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6482 color = getPixelColor(device, 480, 360);
6483 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6484 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6485 color = getPixelColor(device, 160, 120);
6486 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6487 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6488 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6490 color = getPixelColor(device, 480, 160);
6491 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6492 } else if(i == 1) {
6493 color = getPixelColor(device, 160, 360);
6494 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6495 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6496 color = getPixelColor(device, 480, 360);
6497 /* Accept the clear color as well in this case, since SW VP returns an error */
6498 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6499 color = getPixelColor(device, 160, 120);
6500 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6501 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6502 color = getPixelColor(device, 480, 160);
6503 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6506 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6507 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6509 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6510 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6512 /* Now find out if the whole streams are re-read, or just the last active value for the
6513 * vertices is used.
6515 hr = IDirect3DDevice9_BeginScene(device);
6516 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6517 if(SUCCEEDED(hr))
6519 float quad1_modified[] = {
6520 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6521 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6522 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6523 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6525 float quad2_modified[] = {
6526 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6527 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6528 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6529 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6532 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6533 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6535 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6536 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6537 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6538 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6540 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6541 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6543 if(i == 3 || i == 2) {
6544 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6545 } else if(i == 1) {
6546 /* Succeeds or fails, depending on SW or HW vertex processing */
6547 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6550 hr = IDirect3DDevice9_EndScene(device);
6551 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6554 color = getPixelColor(device, 480, 350);
6555 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6556 * as well.
6558 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6559 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6560 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6561 * refrast's result.
6563 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6565 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6566 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6571 IDirect3DDevice9_SetVertexShader(device, NULL);
6572 IDirect3DDevice9_SetPixelShader(device, NULL);
6573 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6575 IDirect3DVertexShader9_Release(swapped_shader);
6578 for(i = 1; i <= 3; i++) {
6579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6580 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6581 if(i == 3) {
6582 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6584 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6585 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6586 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6588 } else if(i == 2){
6589 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6590 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6591 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6593 } else if(i == 1) {
6594 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6595 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6596 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6597 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6600 hr = IDirect3DDevice9_BeginScene(device);
6601 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6602 if(SUCCEEDED(hr))
6604 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6605 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6606 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6609 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6611 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6612 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6614 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6616 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6617 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6619 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6621 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6622 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6623 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6624 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6626 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6628 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6629 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6631 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6633 hr = IDirect3DDevice9_EndScene(device);
6634 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6636 IDirect3DDevice9_SetVertexShader(device, NULL);
6637 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6638 IDirect3DDevice9_SetPixelShader(device, NULL);
6640 color = getPixelColor(device, 160, 360);
6641 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6642 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6643 color = getPixelColor(device, 480, 360);
6644 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6645 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6646 color = getPixelColor(device, 160, 120);
6647 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6648 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6649 color = getPixelColor(device, 480, 160);
6650 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6651 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6653 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6654 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6656 IDirect3DVertexShader9_Release(texcoord_color_shader);
6657 IDirect3DVertexShader9_Release(color_color_shader);
6660 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6661 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6662 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6663 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6665 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6666 IDirect3DVertexDeclaration9_Release(decl_color_color);
6667 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6668 IDirect3DVertexDeclaration9_Release(decl_color_float);
6670 IDirect3DPixelShader9_Release(ps);
6673 static void srgbtexture_test(IDirect3DDevice9 *device)
6675 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6676 * texture stage state to render a quad using that texture. The resulting
6677 * color components should be 0x36 (~ 0.21), per this formula:
6678 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6679 * This is true where srgb_color > 0.04045.
6681 IDirect3D9 *d3d = NULL;
6682 HRESULT hr;
6683 LPDIRECT3DTEXTURE9 texture = NULL;
6684 LPDIRECT3DSURFACE9 surface = NULL;
6685 D3DLOCKED_RECT lr;
6686 DWORD color;
6687 float quad[] = {
6688 -1.0, 1.0, 0.0, 0.0, 0.0,
6689 1.0, 1.0, 0.0, 1.0, 0.0,
6690 -1.0, -1.0, 0.0, 0.0, 1.0,
6691 1.0, -1.0, 0.0, 1.0, 1.0,
6695 memset(&lr, 0, sizeof(lr));
6696 IDirect3DDevice9_GetDirect3D(device, &d3d);
6697 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6698 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6699 D3DFMT_A8R8G8B8) != D3D_OK) {
6700 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6701 goto out;
6704 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6705 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6706 &texture, NULL);
6707 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6708 if(!texture) {
6709 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6710 goto out;
6712 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6713 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6715 fill_surface(surface, 0xff7f7f7f);
6716 IDirect3DSurface9_Release(surface);
6718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6720 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6723 hr = IDirect3DDevice9_BeginScene(device);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6725 if(SUCCEEDED(hr))
6727 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6728 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6730 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6731 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6735 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6737 hr = IDirect3DDevice9_EndScene(device);
6738 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6741 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6742 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6743 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6744 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6746 color = getPixelColor(device, 320, 240);
6747 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6749 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6752 out:
6753 if(texture) IDirect3DTexture9_Release(texture);
6754 IDirect3D9_Release(d3d);
6757 static void shademode_test(IDirect3DDevice9 *device)
6759 /* Render a quad and try all of the different fixed function shading models. */
6760 HRESULT hr;
6761 DWORD color0, color1;
6762 DWORD color0_gouraud = 0, color1_gouraud = 0;
6763 DWORD shademode = D3DSHADE_FLAT;
6764 DWORD primtype = D3DPT_TRIANGLESTRIP;
6765 LPVOID data = NULL;
6766 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6767 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6768 UINT i, j;
6769 struct vertex quad_strip[] =
6771 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6772 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6773 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6774 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6776 struct vertex quad_list[] =
6778 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6779 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6780 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6782 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6783 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6784 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6787 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6788 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6789 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6790 if (FAILED(hr)) goto bail;
6792 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6793 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6794 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6795 if (FAILED(hr)) goto bail;
6797 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6798 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6800 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6801 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6803 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6804 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6805 memcpy(data, quad_strip, sizeof(quad_strip));
6806 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6807 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6809 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6810 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6811 memcpy(data, quad_list, sizeof(quad_list));
6812 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6813 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6815 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6816 * the color fixups we have to do for FLAT shading will be dependent on that. */
6817 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6818 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6820 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6821 for (j=0; j<2; j++) {
6823 /* Inner loop just changes the D3DRS_SHADEMODE */
6824 for (i=0; i<3; i++) {
6825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6826 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6829 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6831 hr = IDirect3DDevice9_BeginScene(device);
6832 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6833 if(SUCCEEDED(hr))
6835 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6836 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6838 hr = IDirect3DDevice9_EndScene(device);
6839 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6842 /* Sample two spots from the output */
6843 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6844 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6845 switch(shademode) {
6846 case D3DSHADE_FLAT:
6847 /* Should take the color of the first vertex of each triangle */
6848 if (0)
6850 /* This test depends on EXT_provoking_vertex being
6851 * available. This extension is currently (20090810)
6852 * not common enough to let the test fail if it isn't
6853 * present. */
6854 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6855 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6857 shademode = D3DSHADE_GOURAUD;
6858 break;
6859 case D3DSHADE_GOURAUD:
6860 /* Should be an interpolated blend */
6862 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6863 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6864 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6865 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6867 color0_gouraud = color0;
6868 color1_gouraud = color1;
6870 shademode = D3DSHADE_PHONG;
6871 break;
6872 case D3DSHADE_PHONG:
6873 /* Should be the same as GOURAUD, since no hardware implements this */
6874 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6875 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6876 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6877 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6879 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6880 color0_gouraud, color0);
6881 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6882 color1_gouraud, color1);
6883 break;
6887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6890 /* Now, do it all over again with a TRIANGLELIST */
6891 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6892 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6893 primtype = D3DPT_TRIANGLELIST;
6894 shademode = D3DSHADE_FLAT;
6897 bail:
6898 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6899 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6901 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6903 if (vb_strip)
6904 IDirect3DVertexBuffer9_Release(vb_strip);
6905 if (vb_list)
6906 IDirect3DVertexBuffer9_Release(vb_list);
6909 static void alpha_test(IDirect3DDevice9 *device)
6911 HRESULT hr;
6912 IDirect3DTexture9 *offscreenTexture;
6913 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6914 DWORD color;
6916 struct vertex quad1[] =
6918 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6919 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6920 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6921 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6923 struct vertex quad2[] =
6925 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6926 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6927 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6928 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6930 static const float composite_quad[][5] = {
6931 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6932 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6933 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6934 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6937 /* Clear the render target with alpha = 0.5 */
6938 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6939 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6941 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6942 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6944 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6945 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6946 if(!backbuffer) {
6947 goto out;
6950 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6951 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6952 if(!offscreen) {
6953 goto out;
6956 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6957 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6959 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6960 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6961 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6962 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6963 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6964 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6965 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6966 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6968 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6971 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6972 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6974 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6978 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6980 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6983 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6985 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6987 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6989 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6990 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6991 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6992 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6993 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6994 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6995 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7000 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7002 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7004 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7005 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7006 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7007 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7008 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7009 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7011 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7012 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7014 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7015 * Disable alpha blending for the final composition
7017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7018 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7019 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7020 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7022 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7023 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7025 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7026 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7027 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7029 hr = IDirect3DDevice9_EndScene(device);
7030 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7033 color = getPixelColor(device, 160, 360);
7034 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7035 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7037 color = getPixelColor(device, 160, 120);
7038 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7039 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7041 color = getPixelColor(device, 480, 360);
7042 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7043 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7045 color = getPixelColor(device, 480, 120);
7046 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7047 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7049 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7051 out:
7052 /* restore things */
7053 if(backbuffer) {
7054 IDirect3DSurface9_Release(backbuffer);
7056 if(offscreenTexture) {
7057 IDirect3DTexture9_Release(offscreenTexture);
7059 if(offscreen) {
7060 IDirect3DSurface9_Release(offscreen);
7064 struct vertex_shortcolor {
7065 float x, y, z;
7066 unsigned short r, g, b, a;
7068 struct vertex_floatcolor {
7069 float x, y, z;
7070 float r, g, b, a;
7073 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7075 HRESULT hr;
7076 BOOL s_ok, ub_ok, f_ok;
7077 DWORD color, size, i;
7078 void *data;
7079 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7080 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7081 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7082 D3DDECL_END()
7084 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7085 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7086 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7087 D3DDECL_END()
7089 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7090 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7091 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7092 D3DDECL_END()
7094 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7095 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7096 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7097 D3DDECL_END()
7099 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7100 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7101 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7102 D3DDECL_END()
7104 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7105 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7106 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7107 D3DDECL_END()
7109 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7110 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7111 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7112 D3DDECL_END()
7114 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7115 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7116 IDirect3DVertexBuffer9 *vb, *vb2;
7117 struct vertex quad1[] = /* D3DCOLOR */
7119 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7120 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7121 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7122 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7124 struct vertex quad2[] = /* UBYTE4N */
7126 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7127 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7128 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7129 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7131 struct vertex_shortcolor quad3[] = /* short */
7133 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7134 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7135 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7136 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7138 struct vertex_floatcolor quad4[] =
7140 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7141 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7142 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7143 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7145 DWORD colors[] = {
7146 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7147 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7148 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7149 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7150 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7151 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7152 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7153 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7154 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7155 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7156 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7157 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7158 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7159 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7160 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7161 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7163 float quads[] = {
7164 -1.0, -1.0, 0.1,
7165 -1.0, 0.0, 0.1,
7166 0.0, -1.0, 0.1,
7167 0.0, 0.0, 0.1,
7169 0.0, -1.0, 0.1,
7170 0.0, 0.0, 0.1,
7171 1.0, -1.0, 0.1,
7172 1.0, 0.0, 0.1,
7174 0.0, 0.0, 0.1,
7175 0.0, 1.0, 0.1,
7176 1.0, 0.0, 0.1,
7177 1.0, 1.0, 0.1,
7179 -1.0, 0.0, 0.1,
7180 -1.0, 1.0, 0.1,
7181 0.0, 0.0, 0.1,
7182 0.0, 1.0, 0.1
7184 struct tvertex quad_transformed[] = {
7185 { 90, 110, 0.1, 2.0, 0x00ffff00},
7186 { 570, 110, 0.1, 2.0, 0x00ffff00},
7187 { 90, 300, 0.1, 2.0, 0x00ffff00},
7188 { 570, 300, 0.1, 2.0, 0x00ffff00}
7190 D3DCAPS9 caps;
7192 memset(&caps, 0, sizeof(caps));
7193 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7194 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7196 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7197 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7199 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7200 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7201 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7202 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7203 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7204 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7205 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7206 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7207 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7208 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7209 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7210 } else {
7211 trace("D3DDTCAPS_UBYTE4N not supported\n");
7212 dcl_ubyte_2 = NULL;
7213 dcl_ubyte = NULL;
7215 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7216 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7217 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7218 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7220 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7221 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7222 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7223 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7225 hr = IDirect3DDevice9_BeginScene(device);
7226 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7227 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7228 if(SUCCEEDED(hr)) {
7229 if(dcl_color) {
7230 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7233 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7236 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7237 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7238 * using software vertex processing. Doh!
7240 if(dcl_ubyte) {
7241 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7244 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7245 ub_ok = SUCCEEDED(hr);
7248 if(dcl_short) {
7249 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7250 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7251 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7252 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7253 s_ok = SUCCEEDED(hr);
7256 if(dcl_float) {
7257 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7258 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7259 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7260 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7261 f_ok = SUCCEEDED(hr);
7264 hr = IDirect3DDevice9_EndScene(device);
7265 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7268 if(dcl_short) {
7269 color = getPixelColor(device, 480, 360);
7270 ok(color == 0x000000ff || !s_ok,
7271 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7273 if(dcl_ubyte) {
7274 color = getPixelColor(device, 160, 120);
7275 ok(color == 0x0000ffff || !ub_ok,
7276 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7278 if(dcl_color) {
7279 color = getPixelColor(device, 160, 360);
7280 ok(color == 0x00ffff00,
7281 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7283 if(dcl_float) {
7284 color = getPixelColor(device, 480, 120);
7285 ok(color == 0x00ff0000 || !f_ok,
7286 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7288 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7290 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7291 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7292 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7293 * whether the immediate mode code works
7295 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7296 hr = IDirect3DDevice9_BeginScene(device);
7297 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7298 if(SUCCEEDED(hr)) {
7299 if(dcl_color) {
7300 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7301 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7302 memcpy(data, quad1, sizeof(quad1));
7303 hr = IDirect3DVertexBuffer9_Unlock(vb);
7304 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7305 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7307 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7308 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7309 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7310 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7313 if(dcl_ubyte) {
7314 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7315 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7316 memcpy(data, quad2, sizeof(quad2));
7317 hr = IDirect3DVertexBuffer9_Unlock(vb);
7318 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7319 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7321 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7322 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7323 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7324 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7325 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7326 ub_ok = SUCCEEDED(hr);
7329 if(dcl_short) {
7330 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7331 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7332 memcpy(data, quad3, sizeof(quad3));
7333 hr = IDirect3DVertexBuffer9_Unlock(vb);
7334 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7335 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7336 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7337 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7338 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7339 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7340 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7341 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7342 s_ok = SUCCEEDED(hr);
7345 if(dcl_float) {
7346 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7347 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7348 memcpy(data, quad4, sizeof(quad4));
7349 hr = IDirect3DVertexBuffer9_Unlock(vb);
7350 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7351 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7353 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7354 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7355 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7356 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7357 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7358 f_ok = SUCCEEDED(hr);
7361 hr = IDirect3DDevice9_EndScene(device);
7362 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7365 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7366 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7367 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7368 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7370 if(dcl_short) {
7371 color = getPixelColor(device, 480, 360);
7372 ok(color == 0x000000ff || !s_ok,
7373 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7375 if(dcl_ubyte) {
7376 color = getPixelColor(device, 160, 120);
7377 ok(color == 0x0000ffff || !ub_ok,
7378 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7380 if(dcl_color) {
7381 color = getPixelColor(device, 160, 360);
7382 ok(color == 0x00ffff00,
7383 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7385 if(dcl_float) {
7386 color = getPixelColor(device, 480, 120);
7387 ok(color == 0x00ff0000 || !f_ok,
7388 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7390 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7395 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7396 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7397 memcpy(data, quad_transformed, sizeof(quad_transformed));
7398 hr = IDirect3DVertexBuffer9_Unlock(vb);
7399 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7401 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7402 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7404 hr = IDirect3DDevice9_BeginScene(device);
7405 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7406 if(SUCCEEDED(hr)) {
7407 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7408 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7409 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7410 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7412 hr = IDirect3DDevice9_EndScene(device);
7413 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7416 color = getPixelColor(device, 88, 108);
7417 ok(color == 0x000000ff,
7418 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7419 color = getPixelColor(device, 92, 108);
7420 ok(color == 0x000000ff,
7421 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7422 color = getPixelColor(device, 88, 112);
7423 ok(color == 0x000000ff,
7424 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7425 color = getPixelColor(device, 92, 112);
7426 ok(color == 0x00ffff00,
7427 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7429 color = getPixelColor(device, 568, 108);
7430 ok(color == 0x000000ff,
7431 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7432 color = getPixelColor(device, 572, 108);
7433 ok(color == 0x000000ff,
7434 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7435 color = getPixelColor(device, 568, 112);
7436 ok(color == 0x00ffff00,
7437 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7438 color = getPixelColor(device, 572, 112);
7439 ok(color == 0x000000ff,
7440 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7442 color = getPixelColor(device, 88, 298);
7443 ok(color == 0x000000ff,
7444 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7445 color = getPixelColor(device, 92, 298);
7446 ok(color == 0x00ffff00,
7447 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7448 color = getPixelColor(device, 88, 302);
7449 ok(color == 0x000000ff,
7450 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7451 color = getPixelColor(device, 92, 302);
7452 ok(color == 0x000000ff,
7453 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7455 color = getPixelColor(device, 568, 298);
7456 ok(color == 0x00ffff00,
7457 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7458 color = getPixelColor(device, 572, 298);
7459 ok(color == 0x000000ff,
7460 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7461 color = getPixelColor(device, 568, 302);
7462 ok(color == 0x000000ff,
7463 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7464 color = getPixelColor(device, 572, 302);
7465 ok(color == 0x000000ff,
7466 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7468 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7470 /* This test is pointless without those two declarations: */
7471 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7472 skip("color-ubyte switching test declarations aren't supported\n");
7473 goto out;
7476 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7477 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7478 memcpy(data, quads, sizeof(quads));
7479 hr = IDirect3DVertexBuffer9_Unlock(vb);
7480 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7481 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7482 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7483 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7484 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7485 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7486 memcpy(data, colors, sizeof(colors));
7487 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7488 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7490 for(i = 0; i < 2; i++) {
7491 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7494 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7496 if(i == 0) {
7497 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7498 } else {
7499 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7501 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7503 hr = IDirect3DDevice9_BeginScene(device);
7504 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7505 ub_ok = FALSE;
7506 if(SUCCEEDED(hr)) {
7507 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7508 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7509 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7510 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7511 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7512 ub_ok = SUCCEEDED(hr);
7514 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7515 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7516 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7517 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7519 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7520 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7521 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7522 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7523 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7524 ub_ok = (SUCCEEDED(hr) && ub_ok);
7526 hr = IDirect3DDevice9_EndScene(device);
7527 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7530 if(i == 0) {
7531 color = getPixelColor(device, 480, 360);
7532 ok(color == 0x00ff0000,
7533 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7534 color = getPixelColor(device, 160, 120);
7535 ok(color == 0x00ffffff,
7536 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7537 color = getPixelColor(device, 160, 360);
7538 ok(color == 0x000000ff || !ub_ok,
7539 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7540 color = getPixelColor(device, 480, 120);
7541 ok(color == 0x000000ff || !ub_ok,
7542 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7543 } else {
7544 color = getPixelColor(device, 480, 360);
7545 ok(color == 0x000000ff,
7546 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7547 color = getPixelColor(device, 160, 120);
7548 ok(color == 0x00ffffff,
7549 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7550 color = getPixelColor(device, 160, 360);
7551 ok(color == 0x00ff0000 || !ub_ok,
7552 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7553 color = getPixelColor(device, 480, 120);
7554 ok(color == 0x00ff0000 || !ub_ok,
7555 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7557 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7560 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7561 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7562 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7563 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7564 IDirect3DVertexBuffer9_Release(vb2);
7566 out:
7567 IDirect3DVertexBuffer9_Release(vb);
7568 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7569 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7570 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7571 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7572 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7573 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7574 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7577 struct vertex_float16color {
7578 float x, y, z;
7579 DWORD c1, c2;
7582 static void test_vshader_float16(IDirect3DDevice9 *device)
7584 HRESULT hr;
7585 DWORD color;
7586 void *data;
7587 static const D3DVERTEXELEMENT9 decl_elements[] = {
7588 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7589 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7590 D3DDECL_END()
7592 IDirect3DVertexDeclaration9 *vdecl = NULL;
7593 IDirect3DVertexBuffer9 *buffer = NULL;
7594 IDirect3DVertexShader9 *shader;
7595 DWORD shader_code[] = {
7596 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7597 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7598 0x90e40001, 0x0000ffff
7600 struct vertex_float16color quad[] = {
7601 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7602 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7603 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7604 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7606 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7607 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7608 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7609 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7611 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7612 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7613 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7614 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7616 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7617 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7618 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7619 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7622 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7623 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7625 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7626 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7627 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7628 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7629 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7630 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7632 hr = IDirect3DDevice9_BeginScene(device);
7633 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7634 if(SUCCEEDED(hr)) {
7635 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7636 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7638 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7640 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7642 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7643 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7644 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7646 hr = IDirect3DDevice9_EndScene(device);
7647 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7649 color = getPixelColor(device, 480, 360);
7650 ok(color == 0x00ff0000,
7651 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7652 color = getPixelColor(device, 160, 120);
7653 ok(color == 0x00000000,
7654 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7655 color = getPixelColor(device, 160, 360);
7656 ok(color == 0x0000ff00,
7657 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7658 color = getPixelColor(device, 480, 120);
7659 ok(color == 0x000000ff,
7660 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7661 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7663 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7666 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7667 D3DPOOL_MANAGED, &buffer, NULL);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7669 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7670 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7671 memcpy(data, quad, sizeof(quad));
7672 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7673 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7674 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7675 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7677 hr = IDirect3DDevice9_BeginScene(device);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7679 if(SUCCEEDED(hr)) {
7680 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7682 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7683 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7684 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7685 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7686 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7689 hr = IDirect3DDevice9_EndScene(device);
7690 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7693 color = getPixelColor(device, 480, 360);
7694 ok(color == 0x00ff0000,
7695 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7696 color = getPixelColor(device, 160, 120);
7697 ok(color == 0x00000000,
7698 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7699 color = getPixelColor(device, 160, 360);
7700 ok(color == 0x0000ff00,
7701 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7702 color = getPixelColor(device, 480, 120);
7703 ok(color == 0x000000ff,
7704 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7705 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7707 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7708 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7709 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7710 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7711 IDirect3DDevice9_SetVertexShader(device, NULL);
7712 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7714 IDirect3DVertexDeclaration9_Release(vdecl);
7715 IDirect3DVertexShader9_Release(shader);
7716 IDirect3DVertexBuffer9_Release(buffer);
7719 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7721 D3DCAPS9 caps;
7722 IDirect3DTexture9 *texture;
7723 HRESULT hr;
7724 D3DLOCKED_RECT rect;
7725 unsigned int x, y;
7726 DWORD *dst, color;
7727 const float quad[] = {
7728 -1.0, -1.0, 0.1, -0.2, -0.2,
7729 1.0, -1.0, 0.1, 1.2, -0.2,
7730 -1.0, 1.0, 0.1, -0.2, 1.2,
7731 1.0, 1.0, 0.1, 1.2, 1.2
7733 memset(&caps, 0, sizeof(caps));
7735 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7736 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7737 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7738 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7739 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7740 "Card has conditional NP2 support without power of two restriction set\n");
7741 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7742 return;
7743 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7744 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7745 return;
7748 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7749 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7751 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7754 memset(&rect, 0, sizeof(rect));
7755 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7756 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7757 for(y = 0; y < 10; y++) {
7758 for(x = 0; x < 10; x++) {
7759 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7760 if(x == 0 || x == 9 || y == 0 || y == 9) {
7761 *dst = 0x00ff0000;
7762 } else {
7763 *dst = 0x000000ff;
7767 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7768 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7770 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7771 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7772 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7773 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7774 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7775 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7777 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7779 hr = IDirect3DDevice9_BeginScene(device);
7780 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7781 if(SUCCEEDED(hr)) {
7782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7783 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7785 hr = IDirect3DDevice9_EndScene(device);
7786 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7789 color = getPixelColor(device, 1, 1);
7790 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7791 color = getPixelColor(device, 639, 479);
7792 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7794 color = getPixelColor(device, 135, 101);
7795 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7796 color = getPixelColor(device, 140, 101);
7797 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7798 color = getPixelColor(device, 135, 105);
7799 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7800 color = getPixelColor(device, 140, 105);
7801 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7803 color = getPixelColor(device, 135, 376);
7804 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7805 color = getPixelColor(device, 140, 376);
7806 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7807 color = getPixelColor(device, 135, 379);
7808 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7809 color = getPixelColor(device, 140, 379);
7810 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7812 color = getPixelColor(device, 500, 101);
7813 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7814 color = getPixelColor(device, 504, 101);
7815 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7816 color = getPixelColor(device, 500, 105);
7817 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7818 color = getPixelColor(device, 504, 105);
7819 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7821 color = getPixelColor(device, 500, 376);
7822 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7823 color = getPixelColor(device, 504, 376);
7824 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7825 color = getPixelColor(device, 500, 380);
7826 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7827 color = getPixelColor(device, 504, 380);
7828 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7830 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7832 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7833 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7834 IDirect3DTexture9_Release(texture);
7837 static void vFace_register_test(IDirect3DDevice9 *device)
7839 HRESULT hr;
7840 DWORD color;
7841 const DWORD shader_code[] = {
7842 0xffff0300, /* ps_3_0 */
7843 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7844 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7845 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7846 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7847 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7848 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7849 0x0000ffff /* END */
7851 const DWORD vshader_code[] = {
7852 0xfffe0300, /* vs_3_0 */
7853 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7854 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7855 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7856 0x0000ffff /* end */
7858 IDirect3DPixelShader9 *shader;
7859 IDirect3DVertexShader9 *vshader;
7860 IDirect3DTexture9 *texture;
7861 IDirect3DSurface9 *surface, *backbuffer;
7862 const float quad[] = {
7863 -1.0, -1.0, 0.1,
7864 1.0, -1.0, 0.1,
7865 -1.0, 0.0, 0.1,
7867 1.0, -1.0, 0.1,
7868 1.0, 0.0, 0.1,
7869 -1.0, 0.0, 0.1,
7871 -1.0, 0.0, 0.1,
7872 -1.0, 1.0, 0.1,
7873 1.0, 0.0, 0.1,
7875 1.0, 0.0, 0.1,
7876 -1.0, 1.0, 0.1,
7877 1.0, 1.0, 0.1,
7879 const float blit[] = {
7880 0.0, -1.0, 0.1, 0.0, 0.0,
7881 1.0, -1.0, 0.1, 1.0, 0.0,
7882 0.0, 1.0, 0.1, 0.0, 1.0,
7883 1.0, 1.0, 0.1, 1.0, 1.0,
7886 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7887 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7888 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7889 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7890 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7891 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7892 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7893 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7894 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7895 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7896 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7897 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7898 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7899 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7900 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7903 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7904 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7906 hr = IDirect3DDevice9_BeginScene(device);
7907 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7908 if(SUCCEEDED(hr)) {
7909 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7910 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7911 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7913 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7915 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7916 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7919 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7921 /* Blit the texture onto the back buffer to make it visible */
7922 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7923 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7924 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7925 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7926 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7927 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7928 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7929 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7930 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7931 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7932 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7933 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7935 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7938 hr = IDirect3DDevice9_EndScene(device);
7939 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7942 color = getPixelColor(device, 160, 360);
7943 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7944 color = getPixelColor(device, 160, 120);
7945 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7946 color = getPixelColor(device, 480, 360);
7947 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7948 color = getPixelColor(device, 480, 120);
7949 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7950 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7952 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7953 IDirect3DDevice9_SetTexture(device, 0, NULL);
7954 IDirect3DPixelShader9_Release(shader);
7955 IDirect3DVertexShader9_Release(vshader);
7956 IDirect3DSurface9_Release(surface);
7957 IDirect3DSurface9_Release(backbuffer);
7958 IDirect3DTexture9_Release(texture);
7961 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7963 HRESULT hr;
7964 DWORD color;
7965 int i;
7966 D3DCAPS9 caps;
7967 BOOL L6V5U5_supported = FALSE;
7968 IDirect3DTexture9 *tex1, *tex2;
7969 D3DLOCKED_RECT locked_rect;
7971 static const float quad[][7] = {
7972 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7973 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7974 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7975 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7978 static const D3DVERTEXELEMENT9 decl_elements[] = {
7979 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7980 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7981 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7982 D3DDECL_END()
7985 /* use asymmetric matrix to test loading */
7986 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7987 float scale, offset;
7989 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7990 IDirect3DTexture9 *texture = NULL;
7992 memset(&caps, 0, sizeof(caps));
7993 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7994 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7995 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7996 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7997 return;
7998 } else {
7999 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8000 * They report that it is not supported, but after that bump mapping works properly. So just test
8001 * if the format is generally supported, and check the BUMPENVMAP flag
8003 IDirect3D9 *d3d9;
8005 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8006 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8007 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8008 L6V5U5_supported = SUCCEEDED(hr);
8009 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8010 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8011 IDirect3D9_Release(d3d9);
8012 if(FAILED(hr)) {
8013 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8014 return;
8018 /* Generate the textures */
8019 generate_bumpmap_textures(device);
8021 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8022 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8024 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8026 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8027 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8028 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8030 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8031 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8032 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8033 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8034 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8035 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8037 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8038 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8039 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8040 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8041 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8042 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8044 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8045 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8047 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8048 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8051 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8054 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8055 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8056 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8057 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8059 hr = IDirect3DDevice9_BeginScene(device);
8060 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8063 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8065 hr = IDirect3DDevice9_EndScene(device);
8066 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8068 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8069 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8070 * But since testing the color match is not the purpose of the test don't be too picky
8072 color = getPixelColor(device, 320-32, 240);
8073 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8074 color = getPixelColor(device, 320+32, 240);
8075 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8076 color = getPixelColor(device, 320, 240-32);
8077 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8078 color = getPixelColor(device, 320, 240+32);
8079 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8080 color = getPixelColor(device, 320, 240);
8081 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8082 color = getPixelColor(device, 320+32, 240+32);
8083 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8084 color = getPixelColor(device, 320-32, 240+32);
8085 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8086 color = getPixelColor(device, 320+32, 240-32);
8087 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8088 color = getPixelColor(device, 320-32, 240-32);
8089 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8090 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8091 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8093 for(i = 0; i < 2; i++) {
8094 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8095 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8096 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8097 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8098 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8099 IDirect3DTexture9_Release(texture); /* To destroy it */
8102 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8103 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8104 goto cleanup;
8106 if(L6V5U5_supported == FALSE) {
8107 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8108 goto cleanup;
8111 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8112 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8113 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8114 * would only make this test more complicated
8116 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8117 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8118 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8119 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8121 memset(&locked_rect, 0, sizeof(locked_rect));
8122 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8123 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8124 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8125 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8126 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8128 memset(&locked_rect, 0, sizeof(locked_rect));
8129 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8130 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8131 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8132 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8133 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8135 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8136 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8137 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8138 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8141 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8142 scale = 2.0;
8143 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8144 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8145 offset = 0.1;
8146 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8147 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8149 hr = IDirect3DDevice9_BeginScene(device);
8150 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8151 if(SUCCEEDED(hr)) {
8152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8153 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8154 hr = IDirect3DDevice9_EndScene(device);
8155 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8158 color = getPixelColor(device, 320, 240);
8159 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8160 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8161 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8163 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8165 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8167 /* Check a result scale factor > 1.0 */
8168 scale = 10;
8169 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8170 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8171 offset = 10;
8172 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8173 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8175 hr = IDirect3DDevice9_BeginScene(device);
8176 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8177 if(SUCCEEDED(hr)) {
8178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8179 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8180 hr = IDirect3DDevice9_EndScene(device);
8181 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8183 color = getPixelColor(device, 320, 240);
8184 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8185 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8186 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8188 /* Check clamping in the scale factor calculation */
8189 scale = 1000;
8190 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8191 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8192 offset = -1;
8193 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8194 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8196 hr = IDirect3DDevice9_BeginScene(device);
8197 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8198 if(SUCCEEDED(hr)) {
8199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8200 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8201 hr = IDirect3DDevice9_EndScene(device);
8202 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8204 color = getPixelColor(device, 320, 240);
8205 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8206 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8207 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8209 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8210 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8211 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8212 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8214 IDirect3DTexture9_Release(tex1);
8215 IDirect3DTexture9_Release(tex2);
8217 cleanup:
8218 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8219 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8220 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8221 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8223 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8224 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8225 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8228 static void stencil_cull_test(IDirect3DDevice9 *device) {
8229 HRESULT hr;
8230 IDirect3DSurface9 *depthstencil = NULL;
8231 D3DSURFACE_DESC desc;
8232 float quad1[] = {
8233 -1.0, -1.0, 0.1,
8234 0.0, -1.0, 0.1,
8235 -1.0, 0.0, 0.1,
8236 0.0, 0.0, 0.1,
8238 float quad2[] = {
8239 0.0, -1.0, 0.1,
8240 1.0, -1.0, 0.1,
8241 0.0, 0.0, 0.1,
8242 1.0, 0.0, 0.1,
8244 float quad3[] = {
8245 0.0, 0.0, 0.1,
8246 1.0, 0.0, 0.1,
8247 0.0, 1.0, 0.1,
8248 1.0, 1.0, 0.1,
8250 float quad4[] = {
8251 -1.0, 0.0, 0.1,
8252 0.0, 0.0, 0.1,
8253 -1.0, 1.0, 0.1,
8254 0.0, 1.0, 0.1,
8256 struct vertex painter[] = {
8257 {-1.0, -1.0, 0.0, 0x00000000},
8258 { 1.0, -1.0, 0.0, 0x00000000},
8259 {-1.0, 1.0, 0.0, 0x00000000},
8260 { 1.0, 1.0, 0.0, 0x00000000},
8262 WORD indices_cw[] = {0, 1, 3};
8263 WORD indices_ccw[] = {0, 2, 3};
8264 unsigned int i;
8265 DWORD color;
8267 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8268 if(depthstencil == NULL) {
8269 skip("No depth stencil buffer\n");
8270 return;
8272 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8273 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8274 IDirect3DSurface9_Release(depthstencil);
8275 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8276 skip("No 4 or 8 bit stencil surface\n");
8277 return;
8280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8281 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8282 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8296 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8301 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8305 /* First pass: Fill the stencil buffer with some values... */
8306 hr = IDirect3DDevice9_BeginScene(device);
8307 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8308 if(SUCCEEDED(hr))
8310 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8311 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8312 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8313 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8314 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8315 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8316 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8317 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8320 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8322 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8323 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8324 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8325 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8327 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8328 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8331 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8332 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8333 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8334 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8335 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8336 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8337 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8341 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8342 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8343 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8344 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8345 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8346 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8348 hr = IDirect3DDevice9_EndScene(device);
8349 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8352 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8354 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8355 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8356 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8358 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8360 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8362 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8364 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8366 /* 2nd pass: Make the stencil values visible */
8367 hr = IDirect3DDevice9_BeginScene(device);
8368 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8369 if(SUCCEEDED(hr))
8371 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8372 for(i = 0; i < 16; i++) {
8373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8374 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8376 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8377 painter[1].diffuse = (i * 16);
8378 painter[2].diffuse = (i * 16);
8379 painter[3].diffuse = (i * 16);
8380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8381 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8383 hr = IDirect3DDevice9_EndScene(device);
8384 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8388 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8390 color = getPixelColor(device, 160, 420);
8391 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8392 color = getPixelColor(device, 160, 300);
8393 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8395 color = getPixelColor(device, 480, 420);
8396 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8397 color = getPixelColor(device, 480, 300);
8398 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8400 color = getPixelColor(device, 160, 180);
8401 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8402 color = getPixelColor(device, 160, 60);
8403 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8405 color = getPixelColor(device, 480, 180);
8406 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8407 color = getPixelColor(device, 480, 60);
8408 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8410 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8414 static void vpos_register_test(IDirect3DDevice9 *device)
8416 HRESULT hr;
8417 DWORD color;
8418 const DWORD shader_code[] = {
8419 0xffff0300, /* ps_3_0 */
8420 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8421 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8422 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8423 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8424 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8425 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8426 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8427 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8428 0x0000ffff /* end */
8430 const DWORD shader_frac_code[] = {
8431 0xffff0300, /* ps_3_0 */
8432 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8433 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8434 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8435 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8436 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8437 0x0000ffff /* end */
8439 const DWORD vshader_code[] = {
8440 0xfffe0300, /* vs_3_0 */
8441 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8442 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8443 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8444 0x0000ffff /* end */
8446 IDirect3DVertexShader9 *vshader;
8447 IDirect3DPixelShader9 *shader, *shader_frac;
8448 IDirect3DSurface9 *surface = NULL, *backbuffer;
8449 const float quad[] = {
8450 -1.0, -1.0, 0.1, 0.0, 0.0,
8451 1.0, -1.0, 0.1, 1.0, 0.0,
8452 -1.0, 1.0, 0.1, 0.0, 1.0,
8453 1.0, 1.0, 0.1, 1.0, 1.0,
8455 D3DLOCKED_RECT lr;
8456 float constant[4] = {1.0, 0.0, 320, 240};
8457 DWORD *pos;
8459 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8461 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8462 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8463 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8465 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8466 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8467 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8468 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8469 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8470 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8471 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8472 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8473 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8474 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8476 hr = IDirect3DDevice9_BeginScene(device);
8477 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8478 if(SUCCEEDED(hr)) {
8479 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8480 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8482 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8483 hr = IDirect3DDevice9_EndScene(device);
8484 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8487 /* This has to be pixel exact */
8488 color = getPixelColor(device, 319, 239);
8489 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8490 color = getPixelColor(device, 320, 239);
8491 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8492 color = getPixelColor(device, 319, 240);
8493 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8494 color = getPixelColor(device, 320, 240);
8495 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8496 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8498 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8499 &surface, NULL);
8500 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8501 hr = IDirect3DDevice9_BeginScene(device);
8502 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8503 if(SUCCEEDED(hr)) {
8504 constant[2] = 16; constant[3] = 16;
8505 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8506 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8507 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8508 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8510 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8511 hr = IDirect3DDevice9_EndScene(device);
8512 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8514 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8515 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8517 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8518 color = *pos & 0x00ffffff;
8519 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8520 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8521 color = *pos & 0x00ffffff;
8522 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8523 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8524 color = *pos & 0x00ffffff;
8525 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8526 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8527 color = *pos & 0x00ffffff;
8528 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8530 hr = IDirect3DSurface9_UnlockRect(surface);
8531 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8533 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8534 * have full control over the multisampling setting inside this test
8536 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8537 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8538 hr = IDirect3DDevice9_BeginScene(device);
8539 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8540 if(SUCCEEDED(hr)) {
8541 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8542 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8544 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8545 hr = IDirect3DDevice9_EndScene(device);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8548 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8551 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8552 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8554 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8555 color = *pos & 0x00ffffff;
8556 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8558 hr = IDirect3DSurface9_UnlockRect(surface);
8559 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8561 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8562 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8563 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8564 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8565 IDirect3DPixelShader9_Release(shader);
8566 IDirect3DPixelShader9_Release(shader_frac);
8567 IDirect3DVertexShader9_Release(vshader);
8568 if(surface) IDirect3DSurface9_Release(surface);
8569 IDirect3DSurface9_Release(backbuffer);
8572 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8574 D3DCOLOR color;
8576 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8577 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8578 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8579 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8580 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8582 ++r;
8583 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8584 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8585 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8586 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8587 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8589 return TRUE;
8592 static void pointsize_test(IDirect3DDevice9 *device)
8594 HRESULT hr;
8595 D3DCAPS9 caps;
8596 D3DMATRIX matrix;
8597 D3DMATRIX identity;
8598 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8599 DWORD color;
8600 IDirect3DSurface9 *rt, *backbuffer;
8601 IDirect3DTexture9 *tex1, *tex2;
8602 RECT rect = {0, 0, 128, 128};
8603 D3DLOCKED_RECT lr;
8604 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8605 0x00000000, 0x00000000};
8606 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8607 0x00000000, 0x0000ff00};
8609 const float vertices[] = {
8610 64, 64, 0.1,
8611 128, 64, 0.1,
8612 192, 64, 0.1,
8613 256, 64, 0.1,
8614 320, 64, 0.1,
8615 384, 64, 0.1,
8616 448, 64, 0.1,
8617 512, 64, 0.1,
8620 /* 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 */
8621 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;
8622 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;
8623 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;
8624 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;
8626 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;
8627 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;
8628 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;
8629 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;
8631 memset(&caps, 0, sizeof(caps));
8632 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8633 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8634 if(caps.MaxPointSize < 32.0) {
8635 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8636 return;
8639 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8640 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8641 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8642 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8644 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8645 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8646 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8648 hr = IDirect3DDevice9_BeginScene(device);
8649 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8650 if (SUCCEEDED(hr))
8652 ptsize = 15.0;
8653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8654 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8656 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8658 ptsize = 31.0;
8659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8660 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8661 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8662 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8664 ptsize = 30.75;
8665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8666 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8667 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8668 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8670 if (caps.MaxPointSize >= 63.0)
8672 ptsize = 63.0;
8673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8674 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8675 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8676 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8678 ptsize = 62.75;
8679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8680 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8682 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8685 ptsize = 1.0;
8686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8687 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8689 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8691 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8692 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8693 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8694 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8696 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8697 ptsize = 15.0;
8698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8700 ptsize = 1.0;
8701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8702 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8704 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8707 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8709 /* pointsize < pointsize_min < pointsize_max?
8710 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8711 ptsize = 1.0;
8712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8713 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8714 ptsize = 15.0;
8715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8716 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8718 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8721 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8723 hr = IDirect3DDevice9_EndScene(device);
8724 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8727 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8728 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8729 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8731 if (caps.MaxPointSize >= 63.0)
8733 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8734 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8737 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8738 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8739 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8740 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8741 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8743 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8745 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8746 * generates texture coordinates for the point(result: Yes, it does)
8748 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8749 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8750 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8752 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8753 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8755 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8756 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8757 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8758 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8759 memset(&lr, 0, sizeof(lr));
8760 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8761 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8762 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8763 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8764 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8765 memset(&lr, 0, sizeof(lr));
8766 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8767 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8768 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8769 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8770 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8771 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8773 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8774 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8775 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8776 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8777 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8778 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8779 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8780 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8781 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8782 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8783 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8784 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8787 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8788 ptsize = 32.0;
8789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8790 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8792 hr = IDirect3DDevice9_BeginScene(device);
8793 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8794 if(SUCCEEDED(hr))
8796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8797 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8798 hr = IDirect3DDevice9_EndScene(device);
8799 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8802 color = getPixelColor(device, 64-4, 64-4);
8803 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8804 color = getPixelColor(device, 64-4, 64+4);
8805 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8806 color = getPixelColor(device, 64+4, 64+4);
8807 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8808 color = getPixelColor(device, 64+4, 64-4);
8809 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8810 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8812 U(matrix).m[0][0] = 1.0f / 64.0f;
8813 U(matrix).m[1][1] = -1.0f / 64.0f;
8814 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8815 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8817 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8818 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8820 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8821 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8822 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8824 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8825 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8827 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8829 hr = IDirect3DDevice9_BeginScene(device);
8830 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8832 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8833 hr = IDirect3DDevice9_EndScene(device);
8834 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8836 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8837 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8838 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8839 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8840 IDirect3DSurface9_Release(backbuffer);
8841 IDirect3DSurface9_Release(rt);
8843 color = getPixelColor(device, 64-4, 64-4);
8844 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8845 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8846 color = getPixelColor(device, 64+4, 64-4);
8847 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8848 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8849 color = getPixelColor(device, 64-4, 64+4);
8850 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8851 "Expected color 0x00000000, got 0x%08x.\n", color);
8852 color = getPixelColor(device, 64+4, 64+4);
8853 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8854 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8857 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8859 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8860 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8861 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8862 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8863 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8864 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8865 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8866 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8867 IDirect3DTexture9_Release(tex1);
8868 IDirect3DTexture9_Release(tex2);
8870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8871 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8873 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8874 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8875 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8878 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8880 static const DWORD vshader_code[] =
8882 0xfffe0300, /* vs_3_0 */
8883 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8884 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8885 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8886 0x0000ffff /* end */
8888 static const DWORD pshader_code1[] =
8890 0xffff0300, /* ps_3_0 */
8891 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8892 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8893 0x0000ffff /* end */
8895 static const DWORD pshader_code2[] =
8897 0xffff0300, /* ps_3_0 */
8898 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8899 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8900 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8901 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8902 0x0000ffff /* end */
8905 HRESULT hr;
8906 IDirect3DVertexShader9 *vs;
8907 IDirect3DPixelShader9 *ps1, *ps2;
8908 IDirect3DTexture9 *tex1, *tex2;
8909 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8910 D3DCAPS9 caps;
8911 DWORD color;
8912 UINT i, j;
8913 float quad[] = {
8914 -1.0, -1.0, 0.1,
8915 1.0, -1.0, 0.1,
8916 -1.0, 1.0, 0.1,
8917 1.0, 1.0, 0.1,
8919 float texquad[] = {
8920 -1.0, -1.0, 0.1, 0.0, 0.0,
8921 0.0, -1.0, 0.1, 1.0, 0.0,
8922 -1.0, 1.0, 0.1, 0.0, 1.0,
8923 0.0, 1.0, 0.1, 1.0, 1.0,
8925 0.0, -1.0, 0.1, 0.0, 0.0,
8926 1.0, -1.0, 0.1, 1.0, 0.0,
8927 0.0, 1.0, 0.1, 0.0, 1.0,
8928 1.0, 1.0, 0.1, 1.0, 1.0,
8931 memset(&caps, 0, sizeof(caps));
8932 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8933 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8934 if(caps.NumSimultaneousRTs < 2) {
8935 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8936 return;
8939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8940 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8942 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8943 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8944 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8946 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8947 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8948 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8949 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8950 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8951 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8952 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8953 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8954 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8955 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8956 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8957 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8959 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8960 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8961 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8962 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8963 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8964 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8966 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8967 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8968 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8970 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8971 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8972 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8973 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8976 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8977 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8978 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8979 color = getPixelColorFromSurface(readback, 8, 8);
8980 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8981 "Expected color 0x000000ff, got 0x%08x.\n", color);
8982 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8983 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8984 color = getPixelColorFromSurface(readback, 8, 8);
8985 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8986 "Expected color 0x000000ff, got 0x%08x.\n", color);
8988 /* Render targets not written by the pixel shader should be unmodified. */
8989 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8990 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8991 hr = IDirect3DDevice9_BeginScene(device);
8992 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8994 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8995 hr = IDirect3DDevice9_EndScene(device);
8996 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8997 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8998 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8999 color = getPixelColorFromSurface(readback, 8, 8);
9000 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9001 "Expected color 0xff00ff00, got 0x%08x.\n", color);
9002 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9003 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9004 for (i = 6; i < 10; ++i)
9006 for (j = 6; j < 10; ++j)
9008 color = getPixelColorFromSurface(readback, j, i);
9009 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9010 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9014 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9015 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9016 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9017 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9018 color = getPixelColorFromSurface(readback, 8, 8);
9019 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9020 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9021 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9022 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9023 color = getPixelColorFromSurface(readback, 8, 8);
9024 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9025 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9027 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9028 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9030 hr = IDirect3DDevice9_BeginScene(device);
9031 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9032 if(SUCCEEDED(hr)) {
9033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9034 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9036 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9037 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9038 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9039 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9040 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9041 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9042 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9043 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9045 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9047 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9050 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9052 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9053 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9055 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9057 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9058 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9060 hr = IDirect3DDevice9_EndScene(device);
9061 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9064 color = getPixelColor(device, 160, 240);
9065 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9066 color = getPixelColor(device, 480, 240);
9067 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9068 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9070 IDirect3DPixelShader9_Release(ps2);
9071 IDirect3DPixelShader9_Release(ps1);
9072 IDirect3DVertexShader9_Release(vs);
9073 IDirect3DTexture9_Release(tex1);
9074 IDirect3DTexture9_Release(tex2);
9075 IDirect3DSurface9_Release(surf1);
9076 IDirect3DSurface9_Release(surf2);
9077 IDirect3DSurface9_Release(backbuf);
9078 IDirect3DSurface9_Release(readback);
9081 struct formats {
9082 const char *fmtName;
9083 D3DFORMAT textureFormat;
9084 DWORD resultColorBlending;
9085 DWORD resultColorNoBlending;
9088 static const struct formats test_formats[] = {
9089 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9090 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9091 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9092 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9093 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9094 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9095 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9096 { NULL, 0 }
9099 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9101 HRESULT hr;
9102 IDirect3DTexture9 *offscreenTexture = NULL;
9103 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9104 IDirect3D9 *d3d = NULL;
9105 DWORD color;
9106 DWORD r0, g0, b0, r1, g1, b1;
9107 int fmt_index;
9109 static const float quad[][5] = {
9110 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9111 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9112 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9113 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9116 /* Quad with R=0x10, G=0x20 */
9117 static const struct vertex quad1[] = {
9118 {-1.0f, -1.0f, 0.1f, 0x80102000},
9119 {-1.0f, 1.0f, 0.1f, 0x80102000},
9120 { 1.0f, -1.0f, 0.1f, 0x80102000},
9121 { 1.0f, 1.0f, 0.1f, 0x80102000},
9124 /* Quad with R=0x20, G=0x10 */
9125 static const struct vertex quad2[] = {
9126 {-1.0f, -1.0f, 0.1f, 0x80201000},
9127 {-1.0f, 1.0f, 0.1f, 0x80201000},
9128 { 1.0f, -1.0f, 0.1f, 0x80201000},
9129 { 1.0f, 1.0f, 0.1f, 0x80201000},
9132 IDirect3DDevice9_GetDirect3D(device, &d3d);
9134 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9135 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9136 if(!backbuffer) {
9137 goto out;
9140 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9142 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9144 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9145 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9147 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9148 continue;
9151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9152 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9154 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9155 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9156 if(!offscreenTexture) {
9157 continue;
9160 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9161 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9162 if(!offscreen) {
9163 continue;
9166 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9167 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9169 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9170 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9171 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9172 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9173 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9174 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9175 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9176 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9178 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9180 /* Below we will draw two quads with different colors and try to blend them together.
9181 * The result color is compared with the expected outcome.
9183 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9184 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9185 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9186 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9187 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9190 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9192 /* Draw a quad using color 0x0010200 */
9193 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9194 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9195 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9196 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9197 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9198 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9200 /* Draw a quad using color 0x0020100 */
9201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9204 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9206 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9208 /* We don't want to blend the result on the backbuffer */
9209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9212 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9213 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9214 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9215 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9216 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9218 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9219 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9221 /* This time with the texture */
9222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9223 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9225 IDirect3DDevice9_EndScene(device);
9228 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9229 /* Compare the color of the center quad with our expectation */
9230 color = getPixelColor(device, 320, 240);
9231 r0 = (color & 0x00ff0000) >> 16;
9232 g0 = (color & 0x0000ff00) >> 8;
9233 b0 = (color & 0x000000ff) >> 0;
9235 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9236 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9237 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9239 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9240 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9241 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9242 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9243 } else {
9244 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9245 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9246 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9247 color = getPixelColor(device, 320, 240);
9248 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);
9250 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9252 IDirect3DDevice9_SetTexture(device, 0, NULL);
9253 if(offscreenTexture) {
9254 IDirect3DTexture9_Release(offscreenTexture);
9256 if(offscreen) {
9257 IDirect3DSurface9_Release(offscreen);
9261 out:
9262 /* restore things */
9263 if(backbuffer) {
9264 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9265 IDirect3DSurface9_Release(backbuffer);
9269 static void tssargtemp_test(IDirect3DDevice9 *device)
9271 HRESULT hr;
9272 DWORD color;
9273 static const struct vertex quad[] = {
9274 {-1.0, -1.0, 0.1, 0x00ff0000},
9275 { 1.0, -1.0, 0.1, 0x00ff0000},
9276 {-1.0, 1.0, 0.1, 0x00ff0000},
9277 { 1.0, 1.0, 0.1, 0x00ff0000}
9279 D3DCAPS9 caps;
9281 memset(&caps, 0, sizeof(caps));
9282 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9283 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9284 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9285 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9286 return;
9289 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9290 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9292 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9293 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9294 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9295 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9297 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9298 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9299 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9300 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9301 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9302 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9304 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9305 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9306 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9307 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9308 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9309 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9311 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9312 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9316 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9317 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9319 hr = IDirect3DDevice9_BeginScene(device);
9320 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9321 if(SUCCEEDED(hr)) {
9322 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9323 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9324 hr = IDirect3DDevice9_EndScene(device);
9325 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9327 color = getPixelColor(device, 320, 240);
9328 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9329 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9331 /* Set stage 1 back to default */
9332 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9333 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9334 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9335 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9336 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9337 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9338 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9339 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9340 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9341 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9344 struct testdata
9346 DWORD idxVertex; /* number of instances in the first stream */
9347 DWORD idxColor; /* number of instances in the second stream */
9348 DWORD idxInstance; /* should be 1 ?? */
9349 DWORD color1; /* color 1 instance */
9350 DWORD color2; /* color 2 instance */
9351 DWORD color3; /* color 3 instance */
9352 DWORD color4; /* color 4 instance */
9353 WORD strVertex; /* specify which stream to use 0-2*/
9354 WORD strColor;
9355 WORD strInstance;
9358 static const struct testdata testcases[]=
9360 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9361 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9362 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9363 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9364 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9365 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9366 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9367 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9368 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9369 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9370 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9371 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9372 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9373 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9375 This draws one instance on some machines, no instance on others
9376 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9379 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9380 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9384 /* Drawing Indexed Geometry with instances*/
9385 static void stream_test(IDirect3DDevice9 *device)
9387 IDirect3DVertexBuffer9 *vb = NULL;
9388 IDirect3DVertexBuffer9 *vb2 = NULL;
9389 IDirect3DVertexBuffer9 *vb3 = NULL;
9390 IDirect3DIndexBuffer9 *ib = NULL;
9391 IDirect3DVertexDeclaration9 *pDecl = NULL;
9392 IDirect3DVertexShader9 *shader = NULL;
9393 HRESULT hr;
9394 BYTE *data;
9395 DWORD color;
9396 DWORD ind;
9397 unsigned i;
9399 const DWORD shader_code[] =
9401 0xfffe0101, /* vs_1_1 */
9402 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9403 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9404 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9405 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9406 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9407 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9408 0x0000ffff
9411 const float quad[][3] =
9413 {-0.5f, -0.5f, 1.1f}, /*0 */
9414 {-0.5f, 0.5f, 1.1f}, /*1 */
9415 { 0.5f, -0.5f, 1.1f}, /*2 */
9416 { 0.5f, 0.5f, 1.1f}, /*3 */
9419 const float vertcolor[][4] =
9421 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9422 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9423 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9424 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9427 /* 4 position for 4 instances */
9428 const float instancepos[][3] =
9430 {-0.6f,-0.6f, 0.0f},
9431 { 0.6f,-0.6f, 0.0f},
9432 { 0.6f, 0.6f, 0.0f},
9433 {-0.6f, 0.6f, 0.0f},
9436 short indices[] = {0, 1, 2, 1, 2, 3};
9438 D3DVERTEXELEMENT9 decl[] =
9440 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9441 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9442 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9443 D3DDECL_END()
9446 /* set the default value because it isn't done in wine? */
9447 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9448 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9450 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9451 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9452 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9454 /* check wrong cases */
9455 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9456 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9457 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9458 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9459 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9460 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9461 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9462 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9463 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9464 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9465 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9466 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9467 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9468 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9469 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9470 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9471 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9472 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9473 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9474 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9476 /* set the default value back */
9477 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9478 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9480 /* create all VertexBuffers*/
9481 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9482 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9483 if(!vb) {
9484 skip("Failed to create a vertex buffer\n");
9485 return;
9487 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9488 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9489 if(!vb2) {
9490 skip("Failed to create a vertex buffer\n");
9491 goto out;
9493 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9494 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9495 if(!vb3) {
9496 skip("Failed to create a vertex buffer\n");
9497 goto out;
9500 /* create IndexBuffer*/
9501 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9502 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9503 if(!ib) {
9504 skip("Failed to create a index buffer\n");
9505 goto out;
9508 /* copy all Buffers (Vertex + Index)*/
9509 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9510 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9511 memcpy(data, quad, sizeof(quad));
9512 hr = IDirect3DVertexBuffer9_Unlock(vb);
9513 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9514 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9515 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9516 memcpy(data, vertcolor, sizeof(vertcolor));
9517 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9518 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9519 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9520 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9521 memcpy(data, instancepos, sizeof(instancepos));
9522 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9523 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9524 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9525 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9526 memcpy(data, indices, sizeof(indices));
9527 hr = IDirect3DIndexBuffer9_Unlock(ib);
9528 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9530 /* create VertexShader */
9531 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9532 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9533 if(!shader) {
9534 skip("Failed to create a vetex shader\n");
9535 goto out;
9538 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9539 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9541 hr = IDirect3DDevice9_SetIndices(device, ib);
9542 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9544 /* run all tests */
9545 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9547 struct testdata act = testcases[i];
9548 decl[0].Stream = act.strVertex;
9549 decl[1].Stream = act.strColor;
9550 decl[2].Stream = act.strInstance;
9551 /* create VertexDeclarations */
9552 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9553 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9556 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9558 hr = IDirect3DDevice9_BeginScene(device);
9559 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9560 if(SUCCEEDED(hr))
9562 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9563 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9565 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9566 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9567 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9568 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9570 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9571 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9572 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9573 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9575 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9576 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9577 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9578 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9580 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9581 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9582 hr = IDirect3DDevice9_EndScene(device);
9583 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9585 /* set all StreamSource && StreamSourceFreq back to default */
9586 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9587 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9588 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9589 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9590 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9591 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9592 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9593 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9594 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9595 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9596 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9597 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9600 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9601 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9603 color = getPixelColor(device, 160, 360);
9604 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9605 color = getPixelColor(device, 480, 360);
9606 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9607 color = getPixelColor(device, 480, 120);
9608 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9609 color = getPixelColor(device, 160, 120);
9610 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9612 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9613 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9616 hr = IDirect3DDevice9_SetIndices(device, NULL);
9617 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9619 out:
9620 if(vb) IDirect3DVertexBuffer9_Release(vb);
9621 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9622 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9623 if(ib)IDirect3DIndexBuffer9_Release(ib);
9624 if(shader)IDirect3DVertexShader9_Release(shader);
9627 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9628 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9629 IDirect3DTexture9 *dsttex = NULL;
9630 HRESULT hr;
9631 DWORD color;
9632 D3DRECT r1 = {0, 0, 50, 50 };
9633 D3DRECT r2 = {50, 0, 100, 50 };
9634 D3DRECT r3 = {50, 50, 100, 100};
9635 D3DRECT r4 = {0, 50, 50, 100};
9636 const float quad[] = {
9637 -1.0, -1.0, 0.1, 0.0, 0.0,
9638 1.0, -1.0, 0.1, 1.0, 0.0,
9639 -1.0, 1.0, 0.1, 0.0, 1.0,
9640 1.0, 1.0, 0.1, 1.0, 1.0,
9643 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9644 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9646 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9647 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9648 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9649 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9651 if(!src || !dsttex) {
9652 skip("One or more test resources could not be created\n");
9653 goto cleanup;
9656 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9657 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9659 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9660 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9662 /* Clear the StretchRect destination for debugging */
9663 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9666 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9668 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9671 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9673 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9674 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9675 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9676 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9677 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9678 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9680 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9681 * the target -> texture GL blit path
9683 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9684 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9685 IDirect3DSurface9_Release(dst);
9687 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9688 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9690 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9692 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9693 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9694 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9696 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9697 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9699 hr = IDirect3DDevice9_BeginScene(device);
9700 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9701 if(SUCCEEDED(hr)) {
9702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9704 hr = IDirect3DDevice9_EndScene(device);
9705 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9708 color = getPixelColor(device, 160, 360);
9709 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9710 color = getPixelColor(device, 480, 360);
9711 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9712 color = getPixelColor(device, 480, 120);
9713 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9714 color = getPixelColor(device, 160, 120);
9715 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9716 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9717 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9719 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9720 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9722 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9724 cleanup:
9725 if(src) IDirect3DSurface9_Release(src);
9726 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9727 if(dsttex) IDirect3DTexture9_Release(dsttex);
9730 static void texop_test(IDirect3DDevice9 *device)
9732 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9733 IDirect3DTexture9 *texture = NULL;
9734 D3DLOCKED_RECT locked_rect;
9735 D3DCOLOR color;
9736 D3DCAPS9 caps;
9737 HRESULT hr;
9738 unsigned i;
9740 static const struct {
9741 float x, y, z;
9742 float s, t;
9743 D3DCOLOR diffuse;
9744 } quad[] = {
9745 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9746 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9747 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9748 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9751 static const D3DVERTEXELEMENT9 decl_elements[] = {
9752 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9753 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9754 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9755 D3DDECL_END()
9758 static const struct {
9759 D3DTEXTUREOP op;
9760 const char *name;
9761 DWORD caps_flag;
9762 D3DCOLOR result;
9763 } test_data[] = {
9764 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9765 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9766 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9767 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9768 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9769 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9770 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9771 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9772 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9773 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9774 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9775 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9776 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9777 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9778 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9779 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9780 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9781 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9782 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9783 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9784 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9785 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9786 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9789 memset(&caps, 0, sizeof(caps));
9790 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9791 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9793 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9794 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9795 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9796 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9798 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9799 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9800 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9801 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9802 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9803 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9804 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9805 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9806 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9808 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9809 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9811 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9813 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9815 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9816 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9819 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9821 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9823 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9826 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9828 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9830 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9832 skip("tex operation %s not supported\n", test_data[i].name);
9833 continue;
9836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9837 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9839 hr = IDirect3DDevice9_BeginScene(device);
9840 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9842 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9843 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9845 hr = IDirect3DDevice9_EndScene(device);
9846 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9848 color = getPixelColor(device, 320, 240);
9849 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9850 test_data[i].name, color, test_data[i].result);
9852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9853 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9856 if (texture) IDirect3DTexture9_Release(texture);
9857 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9860 static void yuv_color_test(IDirect3DDevice9 *device) {
9861 HRESULT hr;
9862 IDirect3DSurface9 *surface = NULL, *target = NULL;
9863 unsigned int fmt, i;
9864 D3DFORMAT format;
9865 const char *fmt_string;
9866 D3DLOCKED_RECT lr;
9867 IDirect3D9 *d3d;
9868 HRESULT color;
9869 DWORD ref_color_left, ref_color_right;
9871 struct {
9872 DWORD in; /* The input color */
9873 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9874 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9875 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9876 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9877 } test_data[] = {
9878 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9879 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9880 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9881 * that
9883 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9884 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9885 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9886 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9887 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9888 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9889 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9890 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9891 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9892 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9893 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9894 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9895 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9896 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9898 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9899 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9900 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9901 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9904 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9905 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9906 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9907 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9909 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9910 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9912 for(fmt = 0; fmt < 2; fmt++) {
9913 if(fmt == 0) {
9914 format = D3DFMT_UYVY;
9915 fmt_string = "D3DFMT_UYVY";
9916 } else {
9917 format = D3DFMT_YUY2;
9918 fmt_string = "D3DFMT_YUY2";
9921 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9922 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9924 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9925 D3DRTYPE_SURFACE, format) != D3D_OK) {
9926 skip("%s is not supported\n", fmt_string);
9927 continue;
9930 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9931 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9932 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9934 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9935 if(fmt == 0) {
9936 ref_color_left = test_data[i].uyvy_left;
9937 ref_color_right = test_data[i].uyvy_right;
9938 } else {
9939 ref_color_left = test_data[i].yuy2_left;
9940 ref_color_right = test_data[i].yuy2_right;
9943 memset(&lr, 0, sizeof(lr));
9944 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9945 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9946 *((DWORD *) lr.pBits) = test_data[i].in;
9947 hr = IDirect3DSurface9_UnlockRect(surface);
9948 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9951 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9952 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9953 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9955 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9956 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9957 * want to add tests for the filtered pixels as well.
9959 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9960 * differently, so we need a max diff of 16
9962 color = getPixelColor(device, 40, 240);
9964 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9965 * where U != V. Skip the entire test if this bug in this case
9967 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9969 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9970 IDirect3DSurface9_Release(surface);
9971 goto out;
9974 ok(color_match(color, ref_color_left, 18),
9975 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9976 test_data[i].in, color, ref_color_left, fmt_string);
9977 color = getPixelColor(device, 600, 240);
9978 ok(color_match(color, ref_color_right, 18),
9979 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9980 test_data[i].in, color, ref_color_right, fmt_string);
9981 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9982 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9984 IDirect3DSurface9_Release(surface);
9987 out:
9988 IDirect3DSurface9_Release(target);
9989 IDirect3D9_Release(d3d);
9992 static void texop_range_test(IDirect3DDevice9 *device)
9994 static const struct {
9995 float x, y, z;
9996 D3DCOLOR diffuse;
9997 } quad[] = {
9998 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9999 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10000 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10001 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10003 HRESULT hr;
10004 IDirect3DTexture9 *texture;
10005 D3DLOCKED_RECT locked_rect;
10006 D3DCAPS9 caps;
10007 DWORD color;
10009 /* We need ADD and SUBTRACT operations */
10010 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10011 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10012 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10013 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10014 return;
10016 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10017 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10018 return;
10021 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10022 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10023 /* Stage 1: result = diffuse(=1.0) + diffuse
10024 * stage 2: result = result - tfactor(= 0.5)
10026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10027 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10028 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10029 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10030 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10031 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10032 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10033 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10034 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10035 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10036 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10037 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10038 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10039 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10041 hr = IDirect3DDevice9_BeginScene(device);
10042 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10043 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10044 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10045 hr = IDirect3DDevice9_EndScene(device);
10046 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10048 color = getPixelColor(device, 320, 240);
10049 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10050 color);
10051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10052 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10054 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10055 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10056 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10057 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10058 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10059 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10060 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10061 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10062 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10064 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10065 * stage 2: result = result + diffuse(1.0)
10067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10068 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10069 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10070 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10071 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10072 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10073 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10074 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10075 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10076 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10077 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10078 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10079 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10080 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10082 hr = IDirect3DDevice9_BeginScene(device);
10083 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10085 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10086 hr = IDirect3DDevice9_EndScene(device);
10087 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10089 color = getPixelColor(device, 320, 240);
10090 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10091 color);
10092 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10093 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10095 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10096 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10097 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10098 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10099 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10100 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10101 IDirect3DTexture9_Release(texture);
10104 static void alphareplicate_test(IDirect3DDevice9 *device) {
10105 struct vertex quad[] = {
10106 { -1.0, -1.0, 0.1, 0x80ff00ff },
10107 { 1.0, -1.0, 0.1, 0x80ff00ff },
10108 { -1.0, 1.0, 0.1, 0x80ff00ff },
10109 { 1.0, 1.0, 0.1, 0x80ff00ff },
10111 HRESULT hr;
10112 DWORD color;
10114 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10115 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10117 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10118 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10120 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10121 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10122 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10123 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10125 hr = IDirect3DDevice9_BeginScene(device);
10126 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10127 if(SUCCEEDED(hr)) {
10128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10129 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10130 hr = IDirect3DDevice9_EndScene(device);
10131 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10134 color = getPixelColor(device, 320, 240);
10135 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10136 color);
10137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10138 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10141 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10145 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10146 HRESULT hr;
10147 D3DCAPS9 caps;
10148 DWORD color;
10149 struct vertex quad[] = {
10150 { -1.0, -1.0, 0.1, 0x408080c0 },
10151 { 1.0, -1.0, 0.1, 0x408080c0 },
10152 { -1.0, 1.0, 0.1, 0x408080c0 },
10153 { 1.0, 1.0, 0.1, 0x408080c0 },
10156 memset(&caps, 0, sizeof(caps));
10157 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10158 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10159 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10160 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10161 return;
10164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10165 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10167 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10168 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10170 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10171 * mov r0.a, diffuse.a
10172 * mov r0, r0.a
10174 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10175 * 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
10176 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10178 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10179 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10180 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10181 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10182 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10183 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10184 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10185 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10186 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10187 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10188 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10189 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10190 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10191 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10192 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10193 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10195 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10197 hr = IDirect3DDevice9_BeginScene(device);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10199 if(SUCCEEDED(hr)) {
10200 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10201 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10202 hr = IDirect3DDevice9_EndScene(device);
10203 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10206 color = getPixelColor(device, 320, 240);
10207 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10208 color);
10209 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10210 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10212 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10213 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10214 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10215 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10216 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10217 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10220 static void zwriteenable_test(IDirect3DDevice9 *device) {
10221 HRESULT hr;
10222 DWORD color;
10223 struct vertex quad1[] = {
10224 { -1.0, -1.0, 0.1, 0x00ff0000},
10225 { -1.0, 1.0, 0.1, 0x00ff0000},
10226 { 1.0, -1.0, 0.1, 0x00ff0000},
10227 { 1.0, 1.0, 0.1, 0x00ff0000},
10229 struct vertex quad2[] = {
10230 { -1.0, -1.0, 0.9, 0x0000ff00},
10231 { -1.0, 1.0, 0.9, 0x0000ff00},
10232 { 1.0, -1.0, 0.9, 0x0000ff00},
10233 { 1.0, 1.0, 0.9, 0x0000ff00},
10236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10237 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10239 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10240 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10242 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10244 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10246 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10248 hr = IDirect3DDevice9_BeginScene(device);
10249 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10250 if(SUCCEEDED(hr)) {
10251 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10252 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10253 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10254 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10255 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10256 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10259 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10261 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10263 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10265 hr = IDirect3DDevice9_EndScene(device);
10266 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10269 color = getPixelColor(device, 320, 240);
10270 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10271 color);
10272 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10273 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10276 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10279 static void alphatest_test(IDirect3DDevice9 *device) {
10280 #define ALPHATEST_PASSED 0x0000ff00
10281 #define ALPHATEST_FAILED 0x00ff0000
10282 struct {
10283 D3DCMPFUNC func;
10284 DWORD color_less;
10285 DWORD color_equal;
10286 DWORD color_greater;
10287 } testdata[] = {
10288 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10289 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10290 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10291 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10292 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10293 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10294 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10295 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10297 unsigned int i, j;
10298 HRESULT hr;
10299 DWORD color;
10300 struct vertex quad[] = {
10301 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10302 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10303 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10304 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10306 D3DCAPS9 caps;
10308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10310 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10313 for(j = 0; j < 2; j++) {
10314 if(j == 1) {
10315 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10316 * the alpha test either for performance reasons(floating point RTs) or to work
10317 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10318 * codepath for ffp and shader in this case, and the test should cover both
10320 IDirect3DPixelShader9 *ps;
10321 DWORD shader_code[] = {
10322 0xffff0101, /* ps_1_1 */
10323 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10324 0x0000ffff /* end */
10326 memset(&caps, 0, sizeof(caps));
10327 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10328 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10329 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10330 break;
10333 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10334 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10335 IDirect3DDevice9_SetPixelShader(device, ps);
10336 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10337 IDirect3DPixelShader9_Release(ps);
10340 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10341 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10344 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10345 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10347 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10348 hr = IDirect3DDevice9_BeginScene(device);
10349 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10350 if(SUCCEEDED(hr)) {
10351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10352 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10353 hr = IDirect3DDevice9_EndScene(device);
10354 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10356 color = getPixelColor(device, 320, 240);
10357 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10358 color, testdata[i].color_less, testdata[i].func);
10359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10360 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10362 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10363 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10365 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10366 hr = IDirect3DDevice9_BeginScene(device);
10367 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10368 if(SUCCEEDED(hr)) {
10369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10370 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10371 hr = IDirect3DDevice9_EndScene(device);
10372 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10374 color = getPixelColor(device, 320, 240);
10375 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10376 color, testdata[i].color_equal, testdata[i].func);
10377 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10378 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10380 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10381 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10383 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10384 hr = IDirect3DDevice9_BeginScene(device);
10385 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10386 if(SUCCEEDED(hr)) {
10387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10389 hr = IDirect3DDevice9_EndScene(device);
10390 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10392 color = getPixelColor(device, 320, 240);
10393 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10394 color, testdata[i].color_greater, testdata[i].func);
10395 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10396 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10401 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10402 IDirect3DDevice9_SetPixelShader(device, NULL);
10403 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10406 static void sincos_test(IDirect3DDevice9 *device) {
10407 const DWORD sin_shader_code[] = {
10408 0xfffe0200, /* vs_2_0 */
10409 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10410 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10411 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10412 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10413 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10414 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10415 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10416 0x0000ffff /* end */
10418 const DWORD cos_shader_code[] = {
10419 0xfffe0200, /* vs_2_0 */
10420 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10421 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10422 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10423 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10424 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10425 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10426 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10427 0x0000ffff /* end */
10429 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10430 HRESULT hr;
10431 struct {
10432 float x, y, z;
10433 } data[1280];
10434 unsigned int i;
10435 float sincosc1[4] = {D3DSINCOSCONST1};
10436 float sincosc2[4] = {D3DSINCOSCONST2};
10438 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10439 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10441 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10442 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10443 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10444 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10445 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10446 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10447 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10448 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10449 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10450 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10452 /* Generate a point from -1 to 1 every 0.5 pixels */
10453 for(i = 0; i < 1280; i++) {
10454 data[i].x = (-640.0 + i) / 640.0;
10455 data[i].y = 0.0;
10456 data[i].z = 0.1;
10459 hr = IDirect3DDevice9_BeginScene(device);
10460 if(SUCCEEDED(hr)) {
10461 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10462 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10464 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10466 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10467 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10469 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10471 hr = IDirect3DDevice9_EndScene(device);
10472 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10474 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10475 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10476 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10478 IDirect3DDevice9_SetVertexShader(device, NULL);
10479 IDirect3DVertexShader9_Release(sin_shader);
10480 IDirect3DVertexShader9_Release(cos_shader);
10483 static void loop_index_test(IDirect3DDevice9 *device) {
10484 const DWORD shader_code[] = {
10485 0xfffe0200, /* vs_2_0 */
10486 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10487 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10488 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10489 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10490 0x0000001d, /* endloop */
10491 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10492 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10493 0x0000ffff /* END */
10495 IDirect3DVertexShader9 *shader;
10496 HRESULT hr;
10497 DWORD color;
10498 const float quad[] = {
10499 -1.0, -1.0, 0.1,
10500 1.0, -1.0, 0.1,
10501 -1.0, 1.0, 0.1,
10502 1.0, 1.0, 0.1
10504 const float zero[4] = {0, 0, 0, 0};
10505 const float one[4] = {1, 1, 1, 1};
10506 int i0[4] = {2, 10, -3, 0};
10507 float values[4];
10509 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10510 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10511 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10512 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10513 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10514 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10518 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10519 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10520 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10521 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10522 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10523 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10524 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10525 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10526 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10527 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10528 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10529 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10530 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10531 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10532 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10533 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10534 values[0] = 1.0;
10535 values[1] = 1.0;
10536 values[2] = 0.0;
10537 values[3] = 0.0;
10538 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10539 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10540 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10541 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10542 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10543 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10544 values[0] = -1.0;
10545 values[1] = 0.0;
10546 values[2] = 0.0;
10547 values[3] = 0.0;
10548 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10549 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10550 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10551 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10552 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10553 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10554 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10555 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10556 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10557 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10559 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10560 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10562 hr = IDirect3DDevice9_BeginScene(device);
10563 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10564 if(SUCCEEDED(hr))
10566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10567 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10568 hr = IDirect3DDevice9_EndScene(device);
10569 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10571 color = getPixelColor(device, 320, 240);
10572 ok(color_match(color, 0x0000ff00, 1),
10573 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10574 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10575 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10577 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10578 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10579 IDirect3DVertexShader9_Release(shader);
10582 static void sgn_test(IDirect3DDevice9 *device) {
10583 const DWORD shader_code[] = {
10584 0xfffe0200, /* vs_2_0 */
10585 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10586 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10587 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10588 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10589 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10590 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10591 0x0000ffff /* end */
10593 IDirect3DVertexShader9 *shader;
10594 HRESULT hr;
10595 DWORD color;
10596 const float quad[] = {
10597 -1.0, -1.0, 0.1,
10598 1.0, -1.0, 0.1,
10599 -1.0, 1.0, 0.1,
10600 1.0, 1.0, 0.1
10603 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10604 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10605 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10606 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10607 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10608 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10610 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10612 hr = IDirect3DDevice9_BeginScene(device);
10613 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10614 if(SUCCEEDED(hr))
10616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10617 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10618 hr = IDirect3DDevice9_EndScene(device);
10619 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10621 color = getPixelColor(device, 320, 240);
10622 ok(color_match(color, 0x008000ff, 1),
10623 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10624 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10625 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10627 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10628 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10629 IDirect3DVertexShader9_Release(shader);
10632 static void viewport_test(IDirect3DDevice9 *device) {
10633 HRESULT hr;
10634 DWORD color;
10635 D3DVIEWPORT9 vp, old_vp;
10636 BOOL draw_failed = TRUE;
10637 const float quad[] =
10639 -0.5, -0.5, 0.1,
10640 0.5, -0.5, 0.1,
10641 -0.5, 0.5, 0.1,
10642 0.5, 0.5, 0.1
10645 memset(&old_vp, 0, sizeof(old_vp));
10646 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10647 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10650 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10652 /* Test a viewport with Width and Height bigger than the surface dimensions
10654 * TODO: Test Width < surface.width, but X + Width > surface.width
10655 * TODO: Test Width < surface.width, what happens with the height?
10657 * The expected behavior is that the viewport behaves like the "default"
10658 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10659 * MinZ = 0.0, MaxZ = 1.0.
10661 * Starting with Windows 7 the behavior among driver versions is not
10662 * consistent. The SetViewport call is accepted on all drivers. Some
10663 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10664 * nvidia drivers draw, but use the actual values in the viewport and only
10665 * display the upper left part on the surface.
10667 memset(&vp, 0, sizeof(vp));
10668 vp.X = 0;
10669 vp.Y = 0;
10670 vp.Width = 10000;
10671 vp.Height = 10000;
10672 vp.MinZ = 0.0;
10673 vp.MaxZ = 0.0;
10674 hr = IDirect3DDevice9_SetViewport(device, &vp);
10675 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10677 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10678 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10679 hr = IDirect3DDevice9_BeginScene(device);
10680 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10681 if(SUCCEEDED(hr))
10683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10684 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10685 draw_failed = FAILED(hr);
10686 hr = IDirect3DDevice9_EndScene(device);
10687 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10690 if(!draw_failed)
10692 color = getPixelColor(device, 158, 118);
10693 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10694 color = getPixelColor(device, 162, 118);
10695 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10696 color = getPixelColor(device, 158, 122);
10697 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10698 color = getPixelColor(device, 162, 122);
10699 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10701 color = getPixelColor(device, 478, 358);
10702 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10703 color = getPixelColor(device, 482, 358);
10704 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10705 color = getPixelColor(device, 478, 362);
10706 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10707 color = getPixelColor(device, 482, 362);
10708 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10712 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10714 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10715 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10718 /* This test tests depth clamping / clipping behaviour:
10719 * - With software vertex processing, depth values are clamped to the
10720 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10721 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10722 * same as regular vertices here.
10723 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10724 * Normal vertices are always clipped. Pretransformed vertices are
10725 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10726 * - The viewport's MinZ/MaxZ is irrelevant for this.
10728 static void depth_clamp_test(IDirect3DDevice9 *device)
10730 const struct tvertex quad1[] =
10732 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10733 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10734 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10735 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10737 const struct tvertex quad2[] =
10739 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10740 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10741 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10742 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10744 const struct tvertex quad3[] =
10746 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10747 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10748 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10749 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10751 const struct tvertex quad4[] =
10753 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10754 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10755 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10756 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10758 const struct vertex quad5[] =
10760 { -0.5f, 0.5f, 10.0f, 0xff14f914},
10761 { 0.5f, 0.5f, 10.0f, 0xff14f914},
10762 { -0.5f, -0.5f, 10.0f, 0xff14f914},
10763 { 0.5f, -0.5f, 10.0f, 0xff14f914},
10765 const struct vertex quad6[] =
10767 { -1.0f, 0.5f, 10.0f, 0xfff91414},
10768 { 1.0f, 0.5f, 10.0f, 0xfff91414},
10769 { -1.0f, 0.25f, 10.0f, 0xfff91414},
10770 { 1.0f, 0.25f, 10.0f, 0xfff91414},
10773 D3DVIEWPORT9 vp;
10774 D3DCOLOR color;
10775 D3DCAPS9 caps;
10776 HRESULT hr;
10778 vp.X = 0;
10779 vp.Y = 0;
10780 vp.Width = 640;
10781 vp.Height = 480;
10782 vp.MinZ = 0.0;
10783 vp.MaxZ = 7.5;
10785 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10786 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10788 hr = IDirect3DDevice9_SetViewport(device, &vp);
10789 if(FAILED(hr))
10791 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10792 * the tests because the 7.5 is just intended to show that it doesn't have
10793 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10794 * viewport and continue.
10796 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10797 vp.MaxZ = 1.0;
10798 hr = IDirect3DDevice9_SetViewport(device, &vp);
10800 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10802 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10803 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10806 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10808 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10810 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10812 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10814 hr = IDirect3DDevice9_BeginScene(device);
10815 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10817 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10818 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10820 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10821 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10823 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10826 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10829 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10831 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10834 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10836 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10837 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10840 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10843 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10846 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10848 hr = IDirect3DDevice9_EndScene(device);
10849 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10851 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10853 color = getPixelColor(device, 75, 75);
10854 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10855 color = getPixelColor(device, 150, 150);
10856 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10857 color = getPixelColor(device, 320, 240);
10858 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10859 color = getPixelColor(device, 320, 330);
10860 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10861 color = getPixelColor(device, 320, 330);
10862 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10864 else
10866 color = getPixelColor(device, 75, 75);
10867 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10868 color = getPixelColor(device, 150, 150);
10869 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10870 color = getPixelColor(device, 320, 240);
10871 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10872 color = getPixelColor(device, 320, 330);
10873 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10874 color = getPixelColor(device, 320, 330);
10875 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10879 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10881 vp.MinZ = 0.0;
10882 vp.MaxZ = 1.0;
10883 hr = IDirect3DDevice9_SetViewport(device, &vp);
10884 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10887 static void depth_bounds_test(IDirect3DDevice9 *device)
10889 const struct tvertex quad1[] =
10891 { 0, 0, 0.0f, 1, 0xfff9e814},
10892 { 640, 0, 0.0f, 1, 0xfff9e814},
10893 { 0, 480, 1.0f, 1, 0xfff9e814},
10894 { 640, 480, 1.0f, 1, 0xfff9e814},
10896 const struct tvertex quad2[] =
10898 { 0, 0, 0.6f, 1, 0xff002b7f},
10899 { 640, 0, 0.6f, 1, 0xff002b7f},
10900 { 0, 480, 0.6f, 1, 0xff002b7f},
10901 { 640, 480, 0.6f, 1, 0xff002b7f},
10903 const struct tvertex quad3[] =
10905 { 0, 100, 0.6f, 1, 0xfff91414},
10906 { 640, 100, 0.6f, 1, 0xfff91414},
10907 { 0, 160, 0.6f, 1, 0xfff91414},
10908 { 640, 160, 0.6f, 1, 0xfff91414},
10911 union {
10912 DWORD d;
10913 float f;
10914 } tmpvalue;
10916 IDirect3D9 *d3d = NULL;
10917 IDirect3DSurface9 *offscreen_surface = NULL;
10918 D3DCOLOR color;
10919 HRESULT hr;
10921 IDirect3DDevice9_GetDirect3D(device, &d3d);
10922 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10923 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10924 skip("No NVDB (depth bounds test) support\n");
10925 IDirect3D9_Release(d3d);
10926 return;
10928 IDirect3D9_Release(d3d);
10930 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10931 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10932 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10933 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10936 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10939 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10941 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10943 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10945 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10948 hr = IDirect3DDevice9_BeginScene(device);
10949 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10951 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10952 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10955 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10958 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10960 tmpvalue.f = 0.625;
10961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10962 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10964 tmpvalue.f = 0.75;
10965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10966 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10971 tmpvalue.f = 0.75;
10972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10973 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10976 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10979 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10981 hr = IDirect3DDevice9_EndScene(device);
10982 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10984 color = getPixelColor(device, 150, 130);
10985 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10986 color = getPixelColor(device, 150, 200);
10987 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10988 color = getPixelColor(device, 150, 300-5);
10989 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10990 color = getPixelColor(device, 150, 300+5);
10991 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10992 color = getPixelColor(device, 150, 330);
10993 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10994 color = getPixelColor(device, 150, 360-5);
10995 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10996 color = getPixelColor(device, 150, 360+5);
10997 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10999 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11000 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11003 static void depth_buffer_test(IDirect3DDevice9 *device)
11005 static const struct vertex quad1[] =
11007 { -1.0, 1.0, 0.33f, 0xff00ff00},
11008 { 1.0, 1.0, 0.33f, 0xff00ff00},
11009 { -1.0, -1.0, 0.33f, 0xff00ff00},
11010 { 1.0, -1.0, 0.33f, 0xff00ff00},
11012 static const struct vertex quad2[] =
11014 { -1.0, 1.0, 0.50f, 0xffff00ff},
11015 { 1.0, 1.0, 0.50f, 0xffff00ff},
11016 { -1.0, -1.0, 0.50f, 0xffff00ff},
11017 { 1.0, -1.0, 0.50f, 0xffff00ff},
11019 static const struct vertex quad3[] =
11021 { -1.0, 1.0, 0.66f, 0xffff0000},
11022 { 1.0, 1.0, 0.66f, 0xffff0000},
11023 { -1.0, -1.0, 0.66f, 0xffff0000},
11024 { 1.0, -1.0, 0.66f, 0xffff0000},
11026 static const DWORD expected_colors[4][4] =
11028 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11029 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11030 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11031 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11034 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11035 unsigned int i, j;
11036 D3DVIEWPORT9 vp;
11037 D3DCOLOR color;
11038 HRESULT hr;
11040 vp.X = 0;
11041 vp.Y = 0;
11042 vp.Width = 640;
11043 vp.Height = 480;
11044 vp.MinZ = 0.0;
11045 vp.MaxZ = 1.0;
11047 hr = IDirect3DDevice9_SetViewport(device, &vp);
11048 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11051 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11053 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11059 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11061 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11062 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11063 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11064 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11065 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11066 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11067 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11068 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11069 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11070 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11071 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11073 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11074 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11076 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11078 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11079 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11081 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11083 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11084 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11086 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11088 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11089 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11090 hr = IDirect3DDevice9_BeginScene(device);
11091 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11092 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11093 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11094 hr = IDirect3DDevice9_EndScene(device);
11095 ok(SUCCEEDED(hr), "EndScene 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(rt3);
11101 IDirect3DSurface9_Release(rt2);
11102 IDirect3DSurface9_Release(rt1);
11104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11105 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11107 hr = IDirect3DDevice9_BeginScene(device);
11108 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11109 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11110 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11112 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11113 hr = IDirect3DDevice9_EndScene(device);
11114 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11116 for (i = 0; i < 4; ++i)
11118 for (j = 0; j < 4; ++j)
11120 unsigned int x = 80 * ((2 * j) + 1);
11121 unsigned int y = 60 * ((2 * i) + 1);
11122 color = getPixelColor(device, x, y);
11123 ok(color_match(color, expected_colors[i][j], 0),
11124 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11128 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11129 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11132 /* Test that partial depth copies work the way they're supposed to. The clear
11133 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11134 * the following draw should only copy back the part that was modified. */
11135 static void depth_buffer2_test(IDirect3DDevice9 *device)
11137 static const struct vertex quad[] =
11139 { -1.0, 1.0, 0.66f, 0xffff0000},
11140 { 1.0, 1.0, 0.66f, 0xffff0000},
11141 { -1.0, -1.0, 0.66f, 0xffff0000},
11142 { 1.0, -1.0, 0.66f, 0xffff0000},
11145 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11146 unsigned int i, j;
11147 D3DVIEWPORT9 vp;
11148 D3DCOLOR color;
11149 HRESULT hr;
11151 vp.X = 0;
11152 vp.Y = 0;
11153 vp.Width = 640;
11154 vp.Height = 480;
11155 vp.MinZ = 0.0;
11156 vp.MaxZ = 1.0;
11158 hr = IDirect3DDevice9_SetViewport(device, &vp);
11159 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11162 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11164 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11166 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11168 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11169 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11170 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11172 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11173 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11174 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11175 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11176 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11177 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11178 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11179 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11182 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11184 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11186 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11187 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11189 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11191 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11192 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11193 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11194 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11196 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11197 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11198 IDirect3DSurface9_Release(backbuffer);
11199 IDirect3DSurface9_Release(rt2);
11200 IDirect3DSurface9_Release(rt1);
11202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11203 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11205 hr = IDirect3DDevice9_BeginScene(device);
11206 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11208 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11209 hr = IDirect3DDevice9_EndScene(device);
11210 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11212 for (i = 0; i < 4; ++i)
11214 for (j = 0; j < 4; ++j)
11216 unsigned int x = 80 * ((2 * j) + 1);
11217 unsigned int y = 60 * ((2 * i) + 1);
11218 color = getPixelColor(device, x, y);
11219 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11220 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11224 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11225 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11228 static void depth_blit_test(IDirect3DDevice9 *device)
11230 static const struct vertex quad1[] =
11232 { -1.0, 1.0, 0.50f, 0xff00ff00},
11233 { 1.0, 1.0, 0.50f, 0xff00ff00},
11234 { -1.0, -1.0, 0.50f, 0xff00ff00},
11235 { 1.0, -1.0, 0.50f, 0xff00ff00},
11237 static const struct vertex quad2[] =
11239 { -1.0, 1.0, 0.66f, 0xff0000ff},
11240 { 1.0, 1.0, 0.66f, 0xff0000ff},
11241 { -1.0, -1.0, 0.66f, 0xff0000ff},
11242 { 1.0, -1.0, 0.66f, 0xff0000ff},
11244 static const DWORD expected_colors[4][4] =
11246 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11247 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11248 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11249 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11252 IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11253 RECT src_rect, dst_rect;
11254 unsigned int i, j;
11255 D3DVIEWPORT9 vp;
11256 D3DCOLOR color;
11257 HRESULT hr;
11259 vp.X = 0;
11260 vp.Y = 0;
11261 vp.Width = 640;
11262 vp.Height = 480;
11263 vp.MinZ = 0.0;
11264 vp.MaxZ = 1.0;
11266 hr = IDirect3DDevice9_SetViewport(device, &vp);
11267 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11269 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11270 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11271 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11272 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11273 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11274 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11275 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11276 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11279 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11281 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11283 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11284 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11285 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11288 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11289 SetRect(&dst_rect, 0, 0, 480, 360);
11290 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11291 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11292 SetRect(&dst_rect, 0, 0, 320, 240);
11293 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11294 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11296 /* Partial blit. */
11297 SetRect(&src_rect, 0, 0, 320, 240);
11298 SetRect(&dst_rect, 0, 0, 320, 240);
11299 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11300 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11301 /* Flipped. */
11302 SetRect(&src_rect, 0, 0, 640, 480);
11303 SetRect(&dst_rect, 0, 480, 640, 0);
11304 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11305 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11306 /* Full, explicit. */
11307 SetRect(&src_rect, 0, 0, 640, 480);
11308 SetRect(&dst_rect, 0, 0, 640, 480);
11309 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11310 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11311 /* Filtered blit. */
11312 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11313 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11314 /* Depth -> color blit.*/
11315 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11316 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11317 IDirect3DSurface9_Release(backbuffer);
11319 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11320 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11321 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11322 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11323 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11324 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11325 IDirect3DSurface9_Release(ds2);
11326 IDirect3DSurface9_Release(ds1);
11328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11329 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11330 hr = IDirect3DDevice9_BeginScene(device);
11331 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11333 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11335 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11336 hr = IDirect3DDevice9_EndScene(device);
11337 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11339 for (i = 0; i < 4; ++i)
11341 for (j = 0; j < 4; ++j)
11343 unsigned int x = 80 * ((2 * j) + 1);
11344 unsigned int y = 60 * ((2 * i) + 1);
11345 color = getPixelColor(device, x, y);
11346 ok(color_match(color, expected_colors[i][j], 0),
11347 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11351 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11352 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11355 static void intz_test(IDirect3DDevice9 *device)
11357 static const DWORD ps_code[] =
11359 0xffff0200, /* ps_2_0 */
11360 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11361 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11362 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11363 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11364 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11365 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11366 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11367 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11368 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11369 0x0000ffff, /* end */
11371 struct
11373 float x, y, z;
11374 float s, t, p, q;
11376 quad[] =
11378 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11379 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11380 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11381 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11383 struct
11385 UINT x, y;
11386 D3DCOLOR color;
11388 expected_colors[] =
11390 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11391 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11392 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11393 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11394 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11395 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11396 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11397 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11400 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11401 IDirect3DTexture9 *texture;
11402 IDirect3DPixelShader9 *ps;
11403 IDirect3DSurface9 *ds;
11404 IDirect3D9 *d3d9;
11405 D3DCAPS9 caps;
11406 HRESULT hr;
11407 UINT i;
11409 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11410 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11411 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11413 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11414 return;
11417 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11418 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11420 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11421 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11422 if (FAILED(hr))
11424 skip("No INTZ support, skipping INTZ test.\n");
11425 return;
11428 IDirect3D9_Release(d3d9);
11430 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11431 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11432 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11433 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11435 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11436 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11437 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11438 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11439 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11440 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11441 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11442 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11444 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11445 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11447 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11449 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11451 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11452 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11453 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11455 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11456 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11457 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11458 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11459 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11460 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11461 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11462 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11463 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11464 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11466 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11467 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11468 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11469 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11470 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11471 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11472 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11473 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11475 /* Setup the depth/stencil surface. */
11476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11477 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11479 hr = IDirect3DDevice9_BeginScene(device);
11480 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11482 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11483 hr = IDirect3DDevice9_EndScene(device);
11484 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11486 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11487 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11488 IDirect3DSurface9_Release(ds);
11489 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11490 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11491 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11492 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11493 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11494 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11496 /* Read the depth values back. */
11497 hr = IDirect3DDevice9_BeginScene(device);
11498 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11499 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11500 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11501 hr = IDirect3DDevice9_EndScene(device);
11502 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11504 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11506 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11507 ok(color_match(color, expected_colors[i].color, 1),
11508 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11509 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11512 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11513 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11515 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11516 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11517 IDirect3DSurface9_Release(original_ds);
11518 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11519 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11520 IDirect3DTexture9_Release(texture);
11521 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11522 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11523 IDirect3DPixelShader9_Release(ps);
11525 IDirect3DSurface9_Release(original_rt);
11526 IDirect3DSurface9_Release(rt);
11529 static void shadow_test(IDirect3DDevice9 *device)
11531 static const DWORD ps_code[] =
11533 0xffff0200, /* ps_2_0 */
11534 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11535 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11536 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11537 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11538 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11539 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11540 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11541 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11542 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11543 0x0000ffff, /* end */
11545 struct
11547 D3DFORMAT format;
11548 const char *name;
11550 formats[] =
11552 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11553 {D3DFMT_D32, "D3DFMT_D32"},
11554 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11555 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11556 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11557 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11558 {D3DFMT_D16, "D3DFMT_D16"},
11559 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11560 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11562 struct
11564 float x, y, z;
11565 float s, t, p, q;
11567 quad[] =
11569 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11570 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11571 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11572 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11574 struct
11576 UINT x, y;
11577 D3DCOLOR color;
11579 expected_colors[] =
11581 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11582 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11583 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11584 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11585 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11586 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11587 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11588 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11591 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11592 IDirect3DPixelShader9 *ps;
11593 IDirect3D9 *d3d9;
11594 D3DCAPS9 caps;
11595 HRESULT hr;
11596 UINT i;
11598 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11599 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11600 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11602 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11603 return;
11606 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11607 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11608 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11609 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11610 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11611 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11613 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11614 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11615 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11616 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11617 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11619 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11620 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11621 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11622 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11624 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11626 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11628 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11630 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11631 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11632 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11633 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11634 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11635 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11636 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11637 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11638 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11639 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11641 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11643 D3DFORMAT format = formats[i].format;
11644 IDirect3DTexture9 *texture;
11645 IDirect3DSurface9 *ds;
11646 unsigned int j;
11648 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11649 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11650 if (FAILED(hr)) continue;
11652 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11653 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11654 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11656 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11657 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11659 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11660 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11662 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11663 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11665 IDirect3DDevice9_SetPixelShader(device, NULL);
11666 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11668 /* Setup the depth/stencil surface. */
11669 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11670 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11672 hr = IDirect3DDevice9_BeginScene(device);
11673 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11675 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11676 hr = IDirect3DDevice9_EndScene(device);
11677 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11679 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11680 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11681 IDirect3DSurface9_Release(ds);
11683 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11684 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11686 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11687 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11689 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11690 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11692 /* Do the actual shadow mapping. */
11693 hr = IDirect3DDevice9_BeginScene(device);
11694 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11696 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11697 hr = IDirect3DDevice9_EndScene(device);
11698 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11700 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11701 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11702 IDirect3DTexture9_Release(texture);
11704 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11706 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11707 ok(color_match(color, expected_colors[j].color, 0),
11708 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11709 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11710 formats[i].name, color);
11713 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11714 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11717 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11718 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11719 IDirect3DPixelShader9_Release(ps);
11721 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11722 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11723 IDirect3DSurface9_Release(original_ds);
11725 IDirect3DSurface9_Release(original_rt);
11726 IDirect3DSurface9_Release(rt);
11728 IDirect3D9_Release(d3d9);
11731 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11733 const struct vertex quad1[] =
11735 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11736 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11737 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
11738 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
11740 const struct vertex quad2[] =
11742 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11743 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11744 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
11745 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
11747 D3DCOLOR color;
11748 HRESULT hr;
11750 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11751 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11753 hr = IDirect3DDevice9_BeginScene(device);
11754 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11756 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11757 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11760 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11761 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11762 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11765 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11767 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11769 hr = IDirect3DDevice9_EndScene(device);
11770 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11772 color = getPixelColor(device, 1, 240);
11773 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11774 color = getPixelColor(device, 638, 240);
11775 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11777 color = getPixelColor(device, 1, 241);
11778 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11779 color = getPixelColor(device, 638, 241);
11780 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11783 static void clip_planes_test(IDirect3DDevice9 *device)
11785 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11787 const DWORD shader_code[] = {
11788 0xfffe0200, /* vs_2_0 */
11789 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11790 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11791 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11792 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11793 0x0000ffff /* end */
11795 IDirect3DVertexShader9 *shader;
11797 IDirect3DTexture9 *offscreen = NULL;
11798 IDirect3DSurface9 *offscreen_surface, *original_rt;
11799 HRESULT hr;
11801 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11802 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11805 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11807 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11809 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11811 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11813 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11814 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11815 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11816 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11818 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11820 clip_planes(device, "Onscreen FFP");
11822 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11823 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11824 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11825 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11826 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11827 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11829 clip_planes(device, "Offscreen FFP");
11831 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11832 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11834 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11835 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11836 IDirect3DDevice9_SetVertexShader(device, shader);
11837 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11839 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11840 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11842 clip_planes(device, "Onscreen vertex shader");
11844 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11847 clip_planes(device, "Offscreen vertex shader");
11849 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11850 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11852 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11853 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11854 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11855 IDirect3DVertexShader9_Release(shader);
11856 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11857 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11858 IDirect3DSurface9_Release(original_rt);
11859 IDirect3DSurface9_Release(offscreen_surface);
11860 IDirect3DTexture9_Release(offscreen);
11863 static void fp_special_test(IDirect3DDevice9 *device)
11865 static const DWORD vs_header[] =
11867 0xfffe0200, /* vs_2_0 */
11868 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11869 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11870 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11873 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11874 static const DWORD vs_pow[] =
11875 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11876 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11877 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11878 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11879 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11880 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11881 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
11882 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
11884 static const DWORD vs_footer[] =
11886 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11887 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11888 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11889 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11890 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11891 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11892 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11893 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11894 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11895 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11896 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11897 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11898 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11899 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11900 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11901 0x0000ffff, /* end */
11904 static const struct
11906 const char *name;
11907 const DWORD *ops;
11908 DWORD size;
11909 D3DCOLOR r600;
11910 D3DCOLOR nv40;
11911 D3DCOLOR nv50;
11913 vs_body[] =
11915 /* The basic ideas here are:
11916 * 2.0 * +/-INF == +/-INF
11917 * NAN != NAN
11919 * The vertex shader value is written to the red component, with 0.0
11920 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11921 * result in 0x00. The pixel shader value is written to the green
11922 * component, but here 0.0 also results in 0x00. The actual value is
11923 * written to the blue component.
11925 * There are considerable differences between graphics cards in how
11926 * these are handled, but pow and nrm never generate INF or NAN. */
11927 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
11928 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
11929 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
11930 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11931 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
11932 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11933 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11934 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000},
11937 static const DWORD ps_code[] =
11939 0xffff0200, /* ps_2_0 */
11940 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11941 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11942 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11943 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11944 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11945 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11946 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11947 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11948 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11949 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11950 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11951 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11952 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11953 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11954 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11955 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11956 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11957 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11958 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11959 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11960 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11961 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11962 0x0000ffff, /* end */
11965 struct
11967 float x, y, z;
11968 float s;
11970 quad[] =
11972 { -1.0f, 1.0f, 0.0f, 0.0f},
11973 { 1.0f, 1.0f, 1.0f, 0.0f},
11974 { -1.0f, -1.0f, 0.0f, 0.0f},
11975 { 1.0f, -1.0f, 1.0f, 0.0f},
11978 IDirect3DPixelShader9 *ps;
11979 UINT body_size = 0;
11980 DWORD *vs_code;
11981 D3DCAPS9 caps;
11982 HRESULT hr;
11983 UINT i;
11985 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11986 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11987 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11989 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11990 return;
11993 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11994 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11996 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11997 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11998 IDirect3DDevice9_SetPixelShader(device, ps);
11999 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12002 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12004 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12005 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12007 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12009 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12012 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12013 memcpy(vs_code, vs_header, sizeof(vs_header));
12015 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12017 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12018 IDirect3DVertexShader9 *vs;
12019 D3DCOLOR color;
12021 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12022 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12023 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12025 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12026 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12027 IDirect3DDevice9_SetVertexShader(device, vs);
12028 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12030 hr = IDirect3DDevice9_BeginScene(device);
12031 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12032 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12033 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12034 hr = IDirect3DDevice9_EndScene(device);
12035 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12037 color = getPixelColor(device, 320, 240);
12038 ok(color_match(color, vs_body[i].r600, 1)
12039 || color_match(color, vs_body[i].nv40, 1)
12040 || color_match(color, vs_body[i].nv50, 1),
12041 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12042 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12044 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12045 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12047 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12048 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12049 IDirect3DVertexShader9_Release(vs);
12052 HeapFree(GetProcessHeap(), 0, vs_code);
12054 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12055 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12056 IDirect3DPixelShader9_Release(ps);
12059 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12061 IDirect3D9 *d3d;
12062 IDirect3DSurface9 *rt, *backbuffer;
12063 IDirect3DTexture9 *texture;
12064 HRESULT hr;
12065 int i;
12066 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12067 static const struct
12069 D3DFORMAT fmt;
12070 const char *name;
12072 formats[] =
12074 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12075 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12076 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12077 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12078 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12080 static const struct
12082 float x, y, z;
12083 float u, v;
12085 quad[] =
12087 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12088 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12089 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12090 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12093 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12094 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12095 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12096 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12097 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12098 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12099 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12100 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12102 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12104 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12106 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12107 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12109 skip("Format %s not supported as render target, skipping test.\n",
12110 formats[i].name);
12111 continue;
12114 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12115 D3DPOOL_DEFAULT, &texture, NULL);
12116 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12118 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12120 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12121 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12122 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12123 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12125 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12127 hr = IDirect3DDevice9_BeginScene(device);
12128 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12129 if(SUCCEEDED(hr))
12131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12132 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12133 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12134 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12136 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12139 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12140 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12141 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12142 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12143 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12145 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12147 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12148 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12149 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12151 hr = IDirect3DDevice9_EndScene(device);
12152 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12155 IDirect3DSurface9_Release(rt);
12156 IDirect3DTexture9_Release(texture);
12158 color = getPixelColor(device, 360, 240);
12159 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12160 D3DUSAGE_QUERY_SRGBWRITE,
12161 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12163 /* Big slop for R5G6B5 */
12164 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12165 formats[i].name, color_srgb, color);
12167 else
12169 /* Big slop for R5G6B5 */
12170 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12171 formats[i].name, color_rgb, color);
12174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12175 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12178 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12179 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12181 IDirect3D9_Release(d3d);
12182 IDirect3DSurface9_Release(backbuffer);
12185 static void ds_size_test(IDirect3DDevice9 *device)
12187 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12188 HRESULT hr;
12189 DWORD num_passes;
12190 struct
12192 float x, y, z;
12194 quad[] =
12196 {-1.0, -1.0, 0.0 },
12197 {-1.0, 1.0, 0.0 },
12198 { 1.0, -1.0, 0.0 },
12199 { 1.0, 1.0, 0.0 }
12202 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12203 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12204 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12205 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12206 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12207 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12210 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12212 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12214 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12215 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12216 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12217 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12218 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12219 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12220 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12221 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12222 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12223 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12225 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12226 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12228 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12229 * but does not change the surface's contents. */
12230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12231 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12232 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12233 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12234 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12235 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12237 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12239 /* Turning on any depth-related state results in a ValidateDevice failure */
12240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12242 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12243 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12244 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12249 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12250 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12251 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12253 /* Try to draw with the device in an invalid state */
12254 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12256 hr = IDirect3DDevice9_BeginScene(device);
12257 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12258 if(SUCCEEDED(hr))
12260 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12261 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12262 hr = IDirect3DDevice9_EndScene(device);
12263 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12265 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12266 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12267 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12270 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12271 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12272 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12273 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12274 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12275 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12277 IDirect3DSurface9_Release(readback);
12278 IDirect3DSurface9_Release(ds);
12279 IDirect3DSurface9_Release(rt);
12280 IDirect3DSurface9_Release(old_rt);
12281 IDirect3DSurface9_Release(old_ds);
12284 static void unbound_sampler_test(IDirect3DDevice9 *device)
12286 HRESULT hr;
12287 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12288 IDirect3DSurface9 *rt, *old_rt;
12289 DWORD color;
12291 static const DWORD ps_code[] =
12293 0xffff0200, /* ps_2_0 */
12294 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12295 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12296 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12297 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12298 0x0000ffff, /* end */
12300 static const DWORD ps_code_cube[] =
12302 0xffff0200, /* ps_2_0 */
12303 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
12304 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12305 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12306 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12307 0x0000ffff, /* end */
12309 static const DWORD ps_code_volume[] =
12311 0xffff0200, /* ps_2_0 */
12312 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
12313 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12314 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12315 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12316 0x0000ffff, /* end */
12319 static const struct
12321 float x, y, z;
12322 float u, v;
12324 quad[] =
12326 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12327 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12328 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12329 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12332 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12333 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12335 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12336 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12337 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12338 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12339 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12340 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12342 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12343 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12345 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12346 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12348 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12349 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12351 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12352 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12354 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12355 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12357 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12358 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12360 hr = IDirect3DDevice9_BeginScene(device);
12361 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12362 if(SUCCEEDED(hr))
12364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12365 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12367 hr = IDirect3DDevice9_EndScene(device);
12368 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12371 color = getPixelColorFromSurface(rt, 32, 32);
12372 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12374 /* Now try with a cube texture */
12375 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12376 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12378 hr = IDirect3DDevice9_BeginScene(device);
12379 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12380 if (SUCCEEDED(hr))
12382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12383 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12385 hr = IDirect3DDevice9_EndScene(device);
12386 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12389 color = getPixelColorFromSurface(rt, 32, 32);
12390 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12392 /* And then with a volume texture */
12393 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12394 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12396 hr = IDirect3DDevice9_BeginScene(device);
12397 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12398 if (SUCCEEDED(hr))
12400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12401 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12403 hr = IDirect3DDevice9_EndScene(device);
12404 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12407 color = getPixelColorFromSurface(rt, 32, 32);
12408 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12410 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12411 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12413 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12414 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12416 IDirect3DSurface9_Release(rt);
12417 IDirect3DSurface9_Release(old_rt);
12418 IDirect3DPixelShader9_Release(ps);
12419 IDirect3DPixelShader9_Release(ps_cube);
12420 IDirect3DPixelShader9_Release(ps_volume);
12423 static void update_surface_test(IDirect3DDevice9 *device)
12425 static const BYTE blocks[][8] =
12427 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12428 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12429 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12430 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12431 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12432 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12433 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12435 static const struct
12437 UINT x, y;
12438 D3DCOLOR color;
12440 expected_colors[] =
12442 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12443 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12444 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12445 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12446 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12447 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12448 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12450 static const struct
12452 float x, y, z, w;
12453 float u, v;
12455 tri[] =
12457 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12458 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12459 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12461 static const RECT rect_2x2 = {0, 0, 2, 2};
12462 static const struct
12464 UINT src_level;
12465 UINT dst_level;
12466 const RECT *r;
12467 HRESULT hr;
12469 block_size_tests[] =
12471 {1, 0, NULL, D3D_OK},
12472 {0, 1, NULL, D3DERR_INVALIDCALL},
12473 {5, 4, NULL, D3DERR_INVALIDCALL},
12474 {4, 5, NULL, D3DERR_INVALIDCALL},
12475 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12476 {5, 5, &rect_2x2, D3D_OK},
12479 IDirect3DSurface9 *src_surface, *dst_surface;
12480 IDirect3DTexture9 *src_tex, *dst_tex;
12481 IDirect3D9 *d3d;
12482 UINT count, i;
12483 HRESULT hr;
12485 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12486 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12488 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12489 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12490 IDirect3D9_Release(d3d);
12491 if (FAILED(hr))
12493 skip("DXT1 not supported, skipping test.\n");
12494 return;
12497 IDirect3D9_Release(d3d);
12499 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12500 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12501 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12502 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12504 count = IDirect3DTexture9_GetLevelCount(src_tex);
12505 ok(count == 7, "Got level count %u, expected 7.\n", count);
12507 for (i = 0; i < count; ++i)
12509 UINT row_count, block_count, x, y;
12510 D3DSURFACE_DESC desc;
12511 BYTE *row, *block;
12512 D3DLOCKED_RECT r;
12514 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12515 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12517 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12518 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12520 row_count = ((desc.Height + 3) & ~3) / 4;
12521 block_count = ((desc.Width + 3) & ~3) / 4;
12522 row = r.pBits;
12524 for (y = 0; y < row_count; ++y)
12526 block = row;
12527 for (x = 0; x < block_count; ++x)
12529 memcpy(block, blocks[i], sizeof(blocks[i]));
12530 block += sizeof(blocks[i]);
12532 row += r.Pitch;
12535 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12536 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12539 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12541 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12542 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12543 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12544 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12546 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12547 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12548 hr, i, block_size_tests[i].hr);
12550 IDirect3DSurface9_Release(dst_surface);
12551 IDirect3DSurface9_Release(src_surface);
12554 for (i = 0; i < count; ++i)
12556 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12557 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12558 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12559 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12561 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12562 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12564 IDirect3DSurface9_Release(dst_surface);
12565 IDirect3DSurface9_Release(src_surface);
12568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12569 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12570 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12571 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12573 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12574 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12575 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12576 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12577 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12578 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12579 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12582 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12584 hr = IDirect3DDevice9_BeginScene(device);
12585 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12587 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12588 hr = IDirect3DDevice9_EndScene(device);
12589 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12591 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12593 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12594 ok(color_match(color, expected_colors[i].color, 0),
12595 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12596 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12600 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12602 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12603 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12604 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12605 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12606 IDirect3DTexture9_Release(dst_tex);
12607 IDirect3DTexture9_Release(src_tex);
12610 START_TEST(visual)
12612 IDirect3DDevice9 *device_ptr;
12613 D3DCAPS9 caps;
12614 HRESULT hr;
12615 DWORD color;
12617 d3d9_handle = LoadLibraryA("d3d9.dll");
12618 if (!d3d9_handle)
12620 skip("Could not load d3d9.dll\n");
12621 return;
12624 device_ptr = init_d3d9();
12625 if (!device_ptr)
12627 skip("Creating the device failed\n");
12628 return;
12631 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12633 /* Check for the reliability of the returned data */
12634 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12635 if(FAILED(hr))
12637 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12638 goto cleanup;
12641 color = getPixelColor(device_ptr, 1, 1);
12642 if(color !=0x00ff0000)
12644 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12645 goto cleanup;
12647 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12649 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12650 if(FAILED(hr))
12652 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12653 goto cleanup;
12656 color = getPixelColor(device_ptr, 639, 479);
12657 if(color != 0x0000ddee)
12659 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12660 goto cleanup;
12662 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12664 /* Now execute the real tests */
12665 depth_clamp_test(device_ptr);
12666 stretchrect_test(device_ptr);
12667 lighting_test(device_ptr);
12668 clear_test(device_ptr);
12669 color_fill_test(device_ptr);
12670 fog_test(device_ptr);
12671 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12673 test_cube_wrap(device_ptr);
12674 } else {
12675 skip("No cube texture support\n");
12677 z_range_test(device_ptr);
12678 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12680 maxmip_test(device_ptr);
12682 else
12684 skip("No mipmap support\n");
12686 offscreen_test(device_ptr);
12687 ds_size_test(device_ptr);
12688 alpha_test(device_ptr);
12689 shademode_test(device_ptr);
12690 srgbtexture_test(device_ptr);
12691 release_buffer_test(device_ptr);
12692 float_texture_test(device_ptr);
12693 g16r16_texture_test(device_ptr);
12694 pixelshader_blending_test(device_ptr);
12695 texture_transform_flags_test(device_ptr);
12696 autogen_mipmap_test(device_ptr);
12697 fixed_function_decl_test(device_ptr);
12698 conditional_np2_repeat_test(device_ptr);
12699 fixed_function_bumpmap_test(device_ptr);
12700 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12701 stencil_cull_test(device_ptr);
12702 } else {
12703 skip("No two sided stencil support\n");
12705 pointsize_test(device_ptr);
12706 tssargtemp_test(device_ptr);
12707 np2_stretch_rect_test(device_ptr);
12708 yuv_color_test(device_ptr);
12709 zwriteenable_test(device_ptr);
12710 alphatest_test(device_ptr);
12711 viewport_test(device_ptr);
12713 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12715 test_constant_clamp_vs(device_ptr);
12716 test_compare_instructions(device_ptr);
12718 else skip("No vs_1_1 support\n");
12720 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12722 test_mova(device_ptr);
12723 loop_index_test(device_ptr);
12724 sincos_test(device_ptr);
12725 sgn_test(device_ptr);
12726 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12727 test_vshader_input(device_ptr);
12728 test_vshader_float16(device_ptr);
12729 stream_test(device_ptr);
12730 } else {
12731 skip("No vs_3_0 support\n");
12734 else skip("No vs_2_0 support\n");
12736 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12738 fog_with_shader_test(device_ptr);
12740 else skip("No vs_1_1 and ps_1_1 support\n");
12742 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12744 texbem_test(device_ptr);
12745 texdepth_test(device_ptr);
12746 texkill_test(device_ptr);
12747 x8l8v8u8_test(device_ptr);
12748 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12749 constant_clamp_ps_test(device_ptr);
12750 cnd_test(device_ptr);
12751 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12752 dp2add_ps_test(device_ptr);
12753 unbound_sampler_test(device_ptr);
12754 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12755 nested_loop_test(device_ptr);
12756 pretransformed_varying_test(device_ptr);
12757 vFace_register_test(device_ptr);
12758 vpos_register_test(device_ptr);
12759 multiple_rendertargets_test(device_ptr);
12760 } else {
12761 skip("No ps_3_0 or vs_3_0 support\n");
12763 } else {
12764 skip("No ps_2_0 support\n");
12768 else skip("No ps_1_1 support\n");
12770 texop_test(device_ptr);
12771 texop_range_test(device_ptr);
12772 alphareplicate_test(device_ptr);
12773 dp3_alpha_test(device_ptr);
12774 depth_buffer_test(device_ptr);
12775 depth_buffer2_test(device_ptr);
12776 depth_blit_test(device_ptr);
12777 intz_test(device_ptr);
12778 shadow_test(device_ptr);
12779 fp_special_test(device_ptr);
12780 depth_bounds_test(device_ptr);
12781 srgbwrite_format_test(device_ptr);
12782 clip_planes_test(device_ptr);
12783 update_surface_test(device_ptr);
12785 cleanup:
12786 if(device_ptr) {
12787 D3DPRESENT_PARAMETERS present_parameters;
12788 IDirect3DSwapChain9 *swapchain;
12789 ULONG ref;
12791 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12792 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12793 IDirect3DSwapChain9_Release(swapchain);
12794 ref = IDirect3DDevice9_Release(device_ptr);
12795 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12796 DestroyWindow(present_parameters.hDeviceWindow);