d3d9/tests: Fix the depth stencil size tests on AMD.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blobfd7f3878093b40547562d165be84ed3cac6385fe
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
114 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115 if (FAILED(hr) || !surf)
117 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118 return 0xdeadbeef;
121 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122 if(FAILED(hr))
124 trace("Can't get the render target, hr=%08x\n", hr);
125 ret = 0xdeadbeed;
126 goto out;
129 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130 if (FAILED(hr))
132 trace("Can't read the render target data, hr=%08x\n", hr);
133 ret = 0xdeadbeec;
134 goto out;
137 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138 if(FAILED(hr))
140 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141 ret = 0xdeadbeeb;
142 goto out;
145 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146 * really important for these tests
148 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149 hr = IDirect3DSurface9_UnlockRect(surf);
150 if(FAILED(hr))
152 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
155 out:
156 if(target) IDirect3DSurface9_Release(target);
157 if(surf) IDirect3DSurface9_Release(surf);
158 return ret;
161 static IDirect3DDevice9 *init_d3d9(void)
163 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164 IDirect3D9 *d3d9_ptr = 0;
165 IDirect3DDevice9 *device_ptr = 0;
166 D3DPRESENT_PARAMETERS present_parameters;
167 HRESULT hr;
168 D3DADAPTER_IDENTIFIER9 identifier;
170 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172 if (!d3d9_create) return NULL;
174 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175 if (!d3d9_ptr)
177 skip("could not create D3D9\n");
178 return NULL;
181 ZeroMemory(&present_parameters, sizeof(present_parameters));
182 present_parameters.Windowed = TRUE;
183 present_parameters.hDeviceWindow = create_window();
184 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185 present_parameters.BackBufferWidth = 640;
186 present_parameters.BackBufferHeight = 480;
187 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188 present_parameters.EnableAutoDepthStencil = TRUE;
189 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
191 memset(&identifier, 0, sizeof(identifier));
192 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194 trace("Driver string: \"%s\"\n", identifier.Driver);
195 trace("Description string: \"%s\"\n", identifier.Description);
196 ok(identifier.Description[0] != '\0', "Empty driver description\n");
197 trace("Device name string: \"%s\"\n", identifier.DeviceName);
198 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
199 trace("Driver version %d.%d.%d.%d\n",
200 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
203 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
204 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
205 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
206 "Failed to create a device, hr %#x.\n", hr);
208 return device_ptr;
211 struct vertex
213 float x, y, z;
214 DWORD diffuse;
217 struct tvertex
219 float x, y, z, rhw;
220 DWORD diffuse;
223 struct nvertex
225 float x, y, z;
226 float nx, ny, nz;
227 DWORD diffuse;
230 static void lighting_test(IDirect3DDevice9 *device)
232 HRESULT hr;
233 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
234 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
235 DWORD color;
236 D3DMATERIAL9 material, old_material;
237 DWORD cop, carg;
238 DWORD old_colorwrite;
240 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
241 0.0f, 1.0f, 0.0f, 0.0f,
242 0.0f, 0.0f, 1.0f, 0.0f,
243 0.0f, 0.0f, 0.0f, 1.0f };
245 struct vertex unlitquad[] =
247 {-1.0f, -1.0f, 0.1f, 0xffff0000},
248 {-1.0f, 0.0f, 0.1f, 0xffff0000},
249 { 0.0f, 0.0f, 0.1f, 0xffff0000},
250 { 0.0f, -1.0f, 0.1f, 0xffff0000},
252 struct vertex litquad[] =
254 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
255 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
256 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
257 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
259 struct nvertex unlitnquad[] =
261 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
262 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
263 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
264 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 struct nvertex litnquad[] =
268 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
269 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
270 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
271 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 WORD Indices[] = {0, 1, 2, 2, 3, 0};
275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
276 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
278 /* Setup some states that may cause issues */
279 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
280 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
281 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
282 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
283 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
286 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
288 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
290 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
296 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
301 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
302 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306 hr = IDirect3DDevice9_SetFVF(device, 0);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309 hr = IDirect3DDevice9_SetFVF(device, fvf);
310 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312 hr = IDirect3DDevice9_BeginScene(device);
313 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
314 if(hr == D3D_OK)
316 /* No lights are defined... That means, lit vertices should be entirely black */
317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
318 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
319 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
320 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
321 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
324 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
327 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329 hr = IDirect3DDevice9_SetFVF(device, nfvf);
330 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
334 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
335 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
336 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
340 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
341 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
342 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344 IDirect3DDevice9_EndScene(device);
345 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
348 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
349 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
350 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
351 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
352 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
353 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
354 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
355 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
357 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
360 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
361 memset(&material, 0, sizeof(material));
362 material.Diffuse.r = 0.0;
363 material.Diffuse.g = 0.0;
364 material.Diffuse.b = 0.0;
365 material.Diffuse.a = 1.0;
366 material.Ambient.r = 0.0;
367 material.Ambient.g = 0.0;
368 material.Ambient.b = 0.0;
369 material.Ambient.a = 0.0;
370 material.Specular.r = 0.0;
371 material.Specular.g = 0.0;
372 material.Specular.b = 0.0;
373 material.Specular.a = 0.0;
374 material.Emissive.r = 0.0;
375 material.Emissive.g = 0.0;
376 material.Emissive.b = 0.0;
377 material.Emissive.a = 0.0;
378 material.Power = 0.0;
379 IDirect3DDevice9_SetMaterial(device, &material);
380 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
383 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
385 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
388 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
389 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
390 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
392 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
393 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
394 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396 hr = IDirect3DDevice9_BeginScene(device);
397 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
398 if(SUCCEEDED(hr)) {
399 struct vertex lighting_test[] = {
400 {-1.0, -1.0, 0.1, 0x8000ff00},
401 { 1.0, -1.0, 0.1, 0x80000000},
402 {-1.0, 1.0, 0.1, 0x8000ff00},
403 { 1.0, 1.0, 0.1, 0x80000000}
405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
406 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
408 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410 hr = IDirect3DDevice9_EndScene(device);
411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
414 color = getPixelColor(device, 320, 240);
415 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
416 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
421 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
423 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
425 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
428 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
434 static void clear_test(IDirect3DDevice9 *device)
436 /* Tests the correctness of clearing parameters */
437 HRESULT hr;
438 D3DRECT rect[2];
439 D3DRECT rect_negneg;
440 DWORD color;
441 D3DVIEWPORT9 old_vp, vp;
442 RECT scissor;
443 DWORD oldColorWrite;
444 BOOL invalid_clear_failed = FALSE;
446 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
449 /* Positive x, negative y */
450 rect[0].x1 = 0;
451 rect[0].y1 = 480;
452 rect[0].x2 = 320;
453 rect[0].y2 = 240;
455 /* Positive x, positive y */
456 rect[1].x1 = 0;
457 rect[1].y1 = 0;
458 rect[1].x2 = 320;
459 rect[1].y2 = 240;
460 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461 * returns D3D_OK, but ignores the rectangle silently
463 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
467 /* negative x, negative y */
468 rect_negneg.x1 = 640;
469 rect_negneg.y1 = 240;
470 rect_negneg.x2 = 320;
471 rect_negneg.y2 = 0;
472 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
476 color = getPixelColor(device, 160, 360); /* lower left quad */
477 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478 color = getPixelColor(device, 160, 120); /* upper left quad */
479 if(invalid_clear_failed) {
480 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482 } else {
483 /* If the negative rectangle was dropped silently, the correct ones are cleared */
484 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
486 color = getPixelColor(device, 480, 360); /* lower right quad */
487 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488 color = getPixelColor(device, 480, 120); /* upper right quad */
489 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
491 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
493 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494 * clear the red quad in the top left part of the render target. For some reason it
495 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498 * pick some obvious value
500 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
503 /* Test how the viewport affects clears */
504 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
509 vp.X = 160;
510 vp.Y = 120;
511 vp.Width = 160;
512 vp.Height = 120;
513 vp.MinZ = 0.0;
514 vp.MaxZ = 1.0;
515 hr = IDirect3DDevice9_SetViewport(device, &vp);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
520 vp.X = 320;
521 vp.Y = 240;
522 vp.Width = 320;
523 vp.Height = 240;
524 vp.MinZ = 0.0;
525 vp.MaxZ = 1.0;
526 hr = IDirect3DDevice9_SetViewport(device, &vp);
527 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528 rect[0].x1 = 160;
529 rect[0].y1 = 120;
530 rect[0].x2 = 480;
531 rect[0].y2 = 360;
532 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
535 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
538 color = getPixelColor(device, 158, 118);
539 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540 color = getPixelColor(device, 162, 118);
541 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542 color = getPixelColor(device, 158, 122);
543 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544 color = getPixelColor(device, 162, 122);
545 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
547 color = getPixelColor(device, 318, 238);
548 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549 color = getPixelColor(device, 322, 238);
550 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551 color = getPixelColor(device, 318, 242);
552 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553 color = getPixelColor(device, 322, 242);
554 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
556 color = getPixelColor(device, 478, 358);
557 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558 color = getPixelColor(device, 482, 358);
559 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560 color = getPixelColor(device, 478, 362);
561 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562 color = getPixelColor(device, 482, 362);
563 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
565 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
567 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570 scissor.left = 160;
571 scissor.right = 480;
572 scissor.top = 120;
573 scissor.bottom = 360;
574 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
587 color = getPixelColor(device, 158, 118);
588 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589 color = getPixelColor(device, 162, 118);
590 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591 color = getPixelColor(device, 158, 122);
592 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593 color = getPixelColor(device, 162, 122);
594 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
596 color = getPixelColor(device, 158, 358);
597 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598 color = getPixelColor(device, 162, 358);
599 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600 color = getPixelColor(device, 158, 358);
601 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602 color = getPixelColor(device, 162, 362);
603 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
605 color = getPixelColor(device, 478, 118);
606 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607 color = getPixelColor(device, 478, 122);
608 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609 color = getPixelColor(device, 482, 122);
610 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611 color = getPixelColor(device, 482, 358);
612 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
614 color = getPixelColor(device, 478, 358);
615 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616 color = getPixelColor(device, 478, 362);
617 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618 color = getPixelColor(device, 482, 358);
619 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620 color = getPixelColor(device, 482, 362);
621 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
623 color = getPixelColor(device, 318, 238);
624 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625 color = getPixelColor(device, 318, 242);
626 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627 color = getPixelColor(device, 322, 238);
628 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629 color = getPixelColor(device, 322, 242);
630 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
632 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
634 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
639 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
649 /* Colorwriteenable does not affect the clear */
650 color = getPixelColor(device, 320, 240);
651 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
653 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
656 static void color_fill_test(IDirect3DDevice9 *device)
658 HRESULT hr;
659 IDirect3DSurface9 *backbuffer = NULL;
660 IDirect3DSurface9 *rt_surface = NULL;
661 IDirect3DSurface9 *offscreen_surface = NULL;
662 DWORD fill_color, color;
664 /* Test ColorFill on a the backbuffer (should pass) */
665 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667 if(backbuffer)
669 fill_color = 0x112233;
670 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
673 color = getPixelColor(device, 0, 0);
674 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
676 IDirect3DSurface9_Release(backbuffer);
679 /* Test ColorFill on a render target surface (should pass) */
680 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682 if(rt_surface)
684 fill_color = 0x445566;
685 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
688 color = getPixelColorFromSurface(rt_surface, 0, 0);
689 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
691 IDirect3DSurface9_Release(rt_surface);
694 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698 if(offscreen_surface)
700 fill_color = 0x778899;
701 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
704 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
707 IDirect3DSurface9_Release(offscreen_surface);
710 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711 offscreen_surface = NULL;
712 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715 if(offscreen_surface)
717 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
720 IDirect3DSurface9_Release(offscreen_surface);
724 typedef struct {
725 float in[4];
726 DWORD out;
727 } test_data_t;
730 * c7 mova ARGB mov ARGB
731 * -2.4 -2 0x00ffff00 -3 0x00ff0000
732 * -1.6 -2 0x00ffff00 -2 0x00ffff00
733 * -0.4 0 0x0000ffff -1 0x0000ff00
734 * 0.4 0 0x0000ffff 0 0x0000ffff
735 * 1.6 2 0x00ff00ff 1 0x000000ff
736 * 2.4 2 0x00ff00ff 2 0x00ff00ff
738 static void test_mova(IDirect3DDevice9 *device)
740 static const DWORD mova_test[] = {
741 0xfffe0200, /* vs_2_0 */
742 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
743 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
744 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
745 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
746 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
747 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
748 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
749 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
750 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
751 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
752 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
753 0x0000ffff /* END */
755 static const DWORD mov_test[] = {
756 0xfffe0101, /* vs_1_1 */
757 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
758 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
759 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
760 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
761 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
762 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
763 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
764 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
765 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
766 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
767 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
768 0x0000ffff /* END */
771 static const test_data_t test_data[2][6] = {
773 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
781 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
790 static const float quad[][3] = {
791 {-1.0f, -1.0f, 0.0f},
792 {-1.0f, 1.0f, 0.0f},
793 { 1.0f, -1.0f, 0.0f},
794 { 1.0f, 1.0f, 0.0f},
797 static const D3DVERTEXELEMENT9 decl_elements[] = {
798 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799 D3DDECL_END()
802 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803 IDirect3DVertexShader9 *mova_shader = NULL;
804 IDirect3DVertexShader9 *mov_shader = NULL;
805 HRESULT hr;
806 UINT i, j;
808 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
817 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819 for(j = 0; j < 2; ++j)
821 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
823 DWORD color;
825 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
828 hr = IDirect3DDevice9_BeginScene(device);
829 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
834 hr = IDirect3DDevice9_EndScene(device);
835 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
837 color = getPixelColor(device, 320, 240);
838 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
841 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
844 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
847 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
851 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
854 IDirect3DVertexDeclaration9_Release(vertex_declaration);
855 IDirect3DVertexShader9_Release(mova_shader);
856 IDirect3DVertexShader9_Release(mov_shader);
859 struct sVertex {
860 float x, y, z;
861 DWORD diffuse;
862 DWORD specular;
865 struct sVertexT {
866 float x, y, z, rhw;
867 DWORD diffuse;
868 DWORD specular;
871 static void fog_test(IDirect3DDevice9 *device)
873 HRESULT hr;
874 D3DCOLOR color;
875 float start = 0.0f, end = 1.0f;
876 D3DCAPS9 caps;
877 int i;
879 /* Gets full z based fog with linear fog, no fog with specular color */
880 struct sVertex untransformed_1[] = {
881 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
882 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
883 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
884 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
886 /* Ok, I am too lazy to deal with transform matrices */
887 struct sVertex untransformed_2[] = {
888 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
889 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
890 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
891 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
893 /* Untransformed ones. Give them a different diffuse color to make the test look
894 * nicer. It also makes making sure that they are drawn correctly easier.
896 struct sVertexT transformed_1[] = {
897 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
898 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
899 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
900 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
902 struct sVertexT transformed_2[] = {
903 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
904 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
905 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
906 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
908 struct vertex rev_fog_quads[] = {
909 {-1.0, -1.0, 0.1, 0x000000ff},
910 {-1.0, 0.0, 0.1, 0x000000ff},
911 { 0.0, 0.0, 0.1, 0x000000ff},
912 { 0.0, -1.0, 0.1, 0x000000ff},
914 { 0.0, -1.0, 0.9, 0x000000ff},
915 { 0.0, 0.0, 0.9, 0x000000ff},
916 { 1.0, 0.0, 0.9, 0x000000ff},
917 { 1.0, -1.0, 0.9, 0x000000ff},
919 { 0.0, 0.0, 0.4, 0x000000ff},
920 { 0.0, 1.0, 0.4, 0x000000ff},
921 { 1.0, 1.0, 0.4, 0x000000ff},
922 { 1.0, 0.0, 0.4, 0x000000ff},
924 {-1.0, 0.0, 0.7, 0x000000ff},
925 {-1.0, 1.0, 0.7, 0x000000ff},
926 { 0.0, 1.0, 0.7, 0x000000ff},
927 { 0.0, 0.0, 0.7, 0x000000ff},
929 WORD Indices[] = {0, 1, 2, 2, 3, 0};
931 const float ident_mat[16] =
933 1.0f, 0.0f, 0.0f, 0.0f,
934 0.0f, 1.0f, 0.0f, 0.0f,
935 0.0f, 0.0f, 1.0f, 0.0f,
936 0.0f, 0.0f, 0.0f, 1.0f
938 const float world_mat1[16] =
940 1.0f, 0.0f, 0.0f, 0.0f,
941 0.0f, 1.0f, 0.0f, 0.0f,
942 0.0f, 0.0f, 1.0f, 0.0f,
943 0.0f, 0.0f, -0.5f, 1.0f
945 const float world_mat2[16] =
947 1.0f, 0.0f, 0.0f, 0.0f,
948 0.0f, 1.0f, 0.0f, 0.0f,
949 0.0f, 0.0f, 1.0f, 0.0f,
950 0.0f, 0.0f, 1.0f, 1.0f
952 const float proj_mat[16] =
954 1.0f, 0.0f, 0.0f, 0.0f,
955 0.0f, 1.0f, 0.0f, 0.0f,
956 0.0f, 0.0f, 1.0f, 0.0f,
957 0.0f, 0.0f, -1.0f, 1.0f
960 const struct sVertex far_quad1[] =
962 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
963 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
964 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
965 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
967 const struct sVertex far_quad2[] =
969 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
970 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
971 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
972 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
975 memset(&caps, 0, sizeof(caps));
976 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
977 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
979 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
981 /* Setup initial states: No lighting, fog on, fog color */
982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
983 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
985 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
987 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
989 /* First test: Both table fog and vertex fog off */
990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
991 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
993 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
995 /* Start = 0, end = 1. Should be default, but set them */
996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
997 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
999 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1001 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1004 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1005 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1006 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1007 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1008 sizeof(untransformed_1[0]));
1009 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1011 /* That makes it use the Z value */
1012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1013 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1014 /* Untransformed, vertex fog != none (or table fog != none):
1015 * Use the Z value as input into the equation
1017 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1018 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1019 sizeof(untransformed_2[0]));
1020 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1022 /* transformed verts */
1023 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1024 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1025 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1026 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1027 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1028 sizeof(transformed_1[0]));
1029 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1032 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1033 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1034 * equation
1036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1037 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1038 sizeof(transformed_2[0]));
1039 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1041 hr = IDirect3DDevice9_EndScene(device);
1042 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1044 else
1046 ok(FALSE, "BeginScene failed\n");
1049 color = getPixelColor(device, 160, 360);
1050 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1051 color = getPixelColor(device, 160, 120);
1052 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1053 color = getPixelColor(device, 480, 120);
1054 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1055 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1057 color = getPixelColor(device, 480, 360);
1058 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1060 else
1062 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1063 * The settings above result in no fogging with vertex fog
1065 color = getPixelColor(device, 480, 120);
1066 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1067 trace("Info: Table fog not supported by this device\n");
1069 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1071 /* Now test the special case fogstart == fogend */
1072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1073 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1075 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1077 start = 512;
1078 end = 512;
1079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1080 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1082 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1084 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1085 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1087 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1089 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1091 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1092 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1093 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1094 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1095 * color and has fixed fogstart and fogend.
1097 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1098 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1099 sizeof(untransformed_1[0]));
1100 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1101 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1102 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1103 sizeof(untransformed_2[0]));
1104 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1106 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1107 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1108 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1109 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1110 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1111 sizeof(transformed_1[0]));
1112 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1114 hr = IDirect3DDevice9_EndScene(device);
1115 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1117 else
1119 ok(FALSE, "BeginScene failed\n");
1121 color = getPixelColor(device, 160, 360);
1122 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1123 color = getPixelColor(device, 160, 120);
1124 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1125 color = getPixelColor(device, 480, 120);
1126 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1127 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1129 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1130 * but without shaders it seems to work everywhere
1132 end = 0.2;
1133 start = 0.8;
1134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1139 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1141 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1142 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1143 * so skip this for now
1145 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1146 const char *mode = (i ? "table" : "vertex");
1147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1148 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1150 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1152 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1153 hr = IDirect3DDevice9_BeginScene(device);
1154 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1155 if(SUCCEEDED(hr)) {
1156 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1157 4, 5, 6, 6, 7, 4,
1158 8, 9, 10, 10, 11, 8,
1159 12, 13, 14, 14, 15, 12};
1161 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1162 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1163 sizeof(rev_fog_quads[0]));
1164 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1166 hr = IDirect3DDevice9_EndScene(device);
1167 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1169 color = getPixelColor(device, 160, 360);
1170 ok(color_match(color, 0x0000ff00, 1),
1171 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1173 color = getPixelColor(device, 160, 120);
1174 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1175 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1177 color = getPixelColor(device, 480, 120);
1178 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1179 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1181 color = getPixelColor(device, 480, 360);
1182 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1184 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1186 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1187 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1188 break;
1192 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1194 /* A simple fog + non-identity world matrix test */
1195 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1196 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1198 start = 0.0;
1199 end = 1.0;
1200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1201 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1203 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1205 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1207 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1210 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1212 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1214 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1215 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1217 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1218 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1219 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1221 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1222 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1223 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1225 hr = IDirect3DDevice9_EndScene(device);
1226 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1228 else
1230 ok(FALSE, "BeginScene failed\n");
1233 color = getPixelColor(device, 160, 360);
1234 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1235 color = getPixelColor(device, 160, 120);
1236 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
1238 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1240 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1241 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1242 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1243 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1244 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1246 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1247 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1249 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1251 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1252 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1254 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1255 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1256 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1258 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1259 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1260 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1262 hr = IDirect3DDevice9_EndScene(device);
1263 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1265 else
1267 ok(FALSE, "BeginScene failed\n");
1270 color = getPixelColor(device, 160, 360);
1271 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1272 color = getPixelColor(device, 160, 120);
1273 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
1275 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1277 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1278 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1279 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1280 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1282 else
1284 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1287 /* Test RANGEFOG vs FOGTABLEMODE */
1288 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1289 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1291 struct sVertex untransformed_3[] =
1293 {-1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1294 {-1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1295 { 1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1296 { 1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1300 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1301 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1302 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1305 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1307 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1308 * is not used, the fog coordinate will be equal to fogstart and the quad not
1309 * fogged. If range fog is used the fog coordinate will be slightly higher and
1310 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1311 * is calculated per vertex and interpolated, so even the center of the screen
1312 * where the difference doesn't matter will be fogged, but check the corners in
1313 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1314 start = 0.5f;
1315 end = 0.50001f;
1316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1317 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1319 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1321 /* Table fog: Range fog is not used */
1322 hr = IDirect3DDevice9_BeginScene(device);
1323 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1324 if (SUCCEEDED(hr))
1326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1327 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1329 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1330 hr = IDirect3DDevice9_EndScene(device);
1331 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1333 color = getPixelColor(device, 10, 10);
1334 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1335 color = getPixelColor(device, 630, 10);
1336 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1337 color = getPixelColor(device, 10, 470);
1338 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1339 color = getPixelColor(device, 630, 470);
1340 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1342 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1343 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1345 /* Vertex fog: Rangefog is used */
1346 hr = IDirect3DDevice9_BeginScene(device);
1347 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1348 if (SUCCEEDED(hr))
1350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1351 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1353 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1355 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1356 hr = IDirect3DDevice9_EndScene(device);
1357 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1359 color = getPixelColor(device, 10, 10);
1360 ok(color == 0x0000ff00, "Rangefog with vertex fog returned color 0x%08x\n", color);
1361 color = getPixelColor(device, 630, 10);
1362 ok(color == 0x0000ff00, "Rangefog with vertex fog returned color 0x%08x\n", color);
1363 color = getPixelColor(device, 10, 470);
1364 ok(color == 0x0000ff00, "Rangefog with vertex fog returned color 0x%08x\n", color);
1365 color = getPixelColor(device, 630, 470);
1366 ok(color == 0x0000ff00, "Rangefog with vertex fog returned color 0x%08x\n", color);
1368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1369 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1372 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1374 else
1376 skip("Range fog or table fog not supported, skipping range fog tests\n");
1379 /* Turn off the fog master switch to avoid confusing other tests */
1380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1381 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1383 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1385 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1388 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1389 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1390 * regardless of the actual addressing mode set. The way this test works is
1391 * that we sample in one of the corners of the cubemap with filtering enabled,
1392 * and check the interpolated color. There are essentially two reasonable
1393 * things an implementation can do: Either pick one of the faces and
1394 * interpolate the edge texel with itself (i.e., clamp within the face), or
1395 * interpolate between the edge texels of the three involved faces. It should
1396 * never involve the border color or the other side (texcoord wrapping) of a
1397 * face in the interpolation. */
1398 static void test_cube_wrap(IDirect3DDevice9 *device)
1400 static const float quad[][6] = {
1401 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1402 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1403 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1404 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1407 static const D3DVERTEXELEMENT9 decl_elements[] = {
1408 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1409 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1410 D3DDECL_END()
1413 static const struct {
1414 D3DTEXTUREADDRESS mode;
1415 const char *name;
1416 } address_modes[] = {
1417 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1418 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1419 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1420 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1421 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1424 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1425 IDirect3DCubeTexture9 *texture = NULL;
1426 IDirect3DSurface9 *surface = NULL;
1427 IDirect3DSurface9 *face_surface;
1428 D3DLOCKED_RECT locked_rect;
1429 HRESULT hr;
1430 UINT x;
1431 INT y, face;
1433 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1434 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1435 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1436 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1438 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1439 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1440 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1442 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1443 D3DPOOL_DEFAULT, &texture, NULL);
1444 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1446 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1447 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1449 for (y = 0; y < 128; ++y)
1451 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1452 for (x = 0; x < 64; ++x)
1454 *ptr++ = 0xff0000ff;
1456 for (x = 64; x < 128; ++x)
1458 *ptr++ = 0xffff0000;
1462 hr = IDirect3DSurface9_UnlockRect(surface);
1463 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1465 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1466 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1468 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1469 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1471 IDirect3DSurface9_Release(face_surface);
1473 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1474 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1476 for (y = 0; y < 128; ++y)
1478 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1479 for (x = 0; x < 64; ++x)
1481 *ptr++ = 0xffff0000;
1483 for (x = 64; x < 128; ++x)
1485 *ptr++ = 0xff0000ff;
1489 hr = IDirect3DSurface9_UnlockRect(surface);
1490 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1492 /* Create cube faces */
1493 for (face = 1; face < 6; ++face)
1495 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1496 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1498 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1499 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1501 IDirect3DSurface9_Release(face_surface);
1504 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1505 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1507 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1508 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1509 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1510 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1511 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1512 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1515 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1517 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1519 DWORD color;
1521 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1522 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1523 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1524 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1526 hr = IDirect3DDevice9_BeginScene(device);
1527 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1530 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1532 hr = IDirect3DDevice9_EndScene(device);
1533 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1535 color = getPixelColor(device, 320, 240);
1536 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1537 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1538 color, address_modes[x].name);
1540 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1541 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1544 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1547 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1548 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1550 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1551 IDirect3DCubeTexture9_Release(texture);
1552 IDirect3DSurface9_Release(surface);
1555 static void offscreen_test(IDirect3DDevice9 *device)
1557 HRESULT hr;
1558 IDirect3DTexture9 *offscreenTexture = NULL;
1559 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1560 DWORD color;
1562 static const float quad[][5] = {
1563 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1564 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1565 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1566 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1569 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1570 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1572 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1573 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1574 if(!offscreenTexture) {
1575 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1576 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1577 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1578 if(!offscreenTexture) {
1579 skip("Cannot create an offscreen render target\n");
1580 goto out;
1584 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1585 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1586 if(!backbuffer) {
1587 goto out;
1590 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1591 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1592 if(!offscreen) {
1593 goto out;
1596 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1597 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1599 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1600 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1601 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1602 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1603 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1604 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1605 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1606 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1608 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1610 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1611 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1612 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1613 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1614 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1616 /* Draw without textures - Should result in a white quad */
1617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1618 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1620 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1621 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1622 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1623 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1625 /* This time with the texture */
1626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1627 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1629 IDirect3DDevice9_EndScene(device);
1632 /* Center quad - should be white */
1633 color = getPixelColor(device, 320, 240);
1634 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1635 /* Some quad in the cleared part of the texture */
1636 color = getPixelColor(device, 170, 240);
1637 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1638 /* Part of the originally cleared back buffer */
1639 color = getPixelColor(device, 10, 10);
1640 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1641 if(0) {
1642 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1643 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1644 * the offscreen rendering mode this test would succeed or fail
1646 color = getPixelColor(device, 10, 470);
1647 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1650 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1652 out:
1653 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1654 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1656 /* restore things */
1657 if(backbuffer) {
1658 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1659 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1660 IDirect3DSurface9_Release(backbuffer);
1662 if(offscreenTexture) {
1663 IDirect3DTexture9_Release(offscreenTexture);
1665 if(offscreen) {
1666 IDirect3DSurface9_Release(offscreen);
1670 /* This test tests fog in combination with shaders.
1671 * What's tested: linear fog (vertex and table) with pixel shader
1672 * linear table fog with non foggy vertex shader
1673 * vertex fog with foggy vertex shader, non-linear
1674 * fog with shader, non-linear fog with foggy shader,
1675 * linear table fog with foggy shader
1677 static void fog_with_shader_test(IDirect3DDevice9 *device)
1679 HRESULT hr;
1680 DWORD color;
1681 union {
1682 float f;
1683 DWORD i;
1684 } start, end;
1685 unsigned int i, j;
1687 /* basic vertex shader without fog computation ("non foggy") */
1688 static const DWORD vertex_shader_code1[] = {
1689 0xfffe0101, /* vs_1_1 */
1690 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1691 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1692 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1693 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1694 0x0000ffff
1696 /* basic vertex shader with reversed fog computation ("foggy") */
1697 static const DWORD vertex_shader_code2[] = {
1698 0xfffe0101, /* vs_1_1 */
1699 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1700 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1701 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1702 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1703 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1704 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1705 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1706 0x0000ffff
1708 /* basic pixel shader */
1709 static const DWORD pixel_shader_code[] = {
1710 0xffff0101, /* ps_1_1 */
1711 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1712 0x0000ffff
1715 static struct vertex quad[] = {
1716 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1717 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1718 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1719 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1722 static const D3DVERTEXELEMENT9 decl_elements[] = {
1723 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1724 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1725 D3DDECL_END()
1728 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1729 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1730 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1732 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1733 static const struct test_data_t {
1734 int vshader;
1735 int pshader;
1736 D3DFOGMODE vfog;
1737 D3DFOGMODE tfog;
1738 unsigned int color[11];
1739 } test_data[] = {
1740 /* only pixel shader: */
1741 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1742 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1743 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1744 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1745 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1746 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1747 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1748 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1749 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1750 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1751 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1752 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1753 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1754 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1755 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1757 /* vertex shader */
1758 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1759 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1760 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1761 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1762 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1763 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1764 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1765 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1766 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1768 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1769 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1770 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1771 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1772 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1773 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1775 /* vertex shader and pixel shader */
1776 /* The next 4 tests would read the fog coord output, but it isn't available.
1777 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1778 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1779 * These tests should be disabled if some other hardware behaves differently
1781 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1782 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1783 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1784 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1785 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1786 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1787 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1788 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1789 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1790 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1791 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1792 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1794 /* These use the Z coordinate with linear table fog */
1795 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1796 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1797 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1798 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1799 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1800 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1801 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1802 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1803 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1804 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1805 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1806 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808 /* Non-linear table fog without fog coord */
1809 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1810 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1811 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1812 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1813 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1814 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1816 #if 0 /* FIXME: these fail on GeForce 8500 */
1817 /* foggy vertex shader */
1818 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1819 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1820 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1821 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1822 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1823 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1824 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1825 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1826 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1827 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1828 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1829 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1830 #endif
1832 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1833 * all using the fixed fog-coord linear fog
1835 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1836 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1837 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1838 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1839 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1840 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1841 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1842 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1843 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1844 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1845 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1846 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1848 /* These use table fog. Here the shader-provided fog coordinate is
1849 * ignored and the z coordinate used instead
1851 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1852 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1853 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1854 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1855 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1856 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1857 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1858 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1859 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1862 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1863 start.f=0.1f;
1864 end.f=0.9f;
1866 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1867 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1868 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1869 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1870 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1871 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1872 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1873 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1875 /* Setup initial states: No lighting, fog on, fog color */
1876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1877 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1879 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1881 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1882 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1883 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1886 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1887 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1888 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1890 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1892 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1894 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1896 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1898 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1899 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1900 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1901 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1903 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1905 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1907 for(j=0; j < 11; j++)
1909 /* Don't use the whole zrange to prevent rounding errors */
1910 quad[0].z = 0.001f + (float)j / 10.02f;
1911 quad[1].z = 0.001f + (float)j / 10.02f;
1912 quad[2].z = 0.001f + (float)j / 10.02f;
1913 quad[3].z = 0.001f + (float)j / 10.02f;
1915 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1916 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1918 hr = IDirect3DDevice9_BeginScene(device);
1919 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1921 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1922 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1924 hr = IDirect3DDevice9_EndScene(device);
1925 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1927 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1928 color = getPixelColor(device, 128, 240);
1929 ok(color_match(color, test_data[i].color[j], 13),
1930 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1931 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1933 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1937 /* reset states */
1938 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1939 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1940 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1941 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1942 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1943 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1945 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1947 IDirect3DVertexShader9_Release(vertex_shader[1]);
1948 IDirect3DVertexShader9_Release(vertex_shader[2]);
1949 IDirect3DPixelShader9_Release(pixel_shader[1]);
1950 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1953 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1954 unsigned int i, x, y;
1955 HRESULT hr;
1956 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1957 D3DLOCKED_RECT locked_rect;
1959 /* Generate the textures */
1960 for(i=0; i<2; i++)
1962 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1963 D3DPOOL_MANAGED, &texture[i], NULL);
1964 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1966 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1967 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968 for (y = 0; y < 128; ++y)
1970 if(i)
1971 { /* Set up black texture with 2x2 texel white spot in the middle */
1972 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1973 for (x = 0; x < 128; ++x)
1975 if(y>62 && y<66 && x>62 && x<66)
1976 *ptr++ = 0xffffffff;
1977 else
1978 *ptr++ = 0xff000000;
1981 else
1982 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1983 * (if multiplied with bumpenvmat)
1985 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1986 for (x = 0; x < 128; ++x)
1988 if(abs(x-64)>abs(y-64))
1990 if(x < 64)
1991 *ptr++ = 0xc000;
1992 else
1993 *ptr++ = 0x4000;
1995 else
1997 if(y < 64)
1998 *ptr++ = 0x0040;
1999 else
2000 *ptr++ = 0x00c0;
2005 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2006 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2008 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2009 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2011 /* Disable texture filtering */
2012 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2013 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2014 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2015 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2017 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2018 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2019 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2020 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2024 /* test the behavior of the texbem instruction
2025 * with normal 2D and projective 2D textures
2027 static void texbem_test(IDirect3DDevice9 *device)
2029 HRESULT hr;
2030 DWORD color;
2031 int i;
2033 static const DWORD pixel_shader_code[] = {
2034 0xffff0101, /* ps_1_1*/
2035 0x00000042, 0xb00f0000, /* tex t0*/
2036 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2037 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2038 0x0000ffff
2040 static const DWORD double_texbem_code[] = {
2041 0xffff0103, /* ps_1_3 */
2042 0x00000042, 0xb00f0000, /* tex t0 */
2043 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2044 0x00000042, 0xb00f0002, /* tex t2 */
2045 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2046 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2047 0x0000ffff /* end */
2051 static const float quad[][7] = {
2052 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2053 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2054 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2055 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2057 static const float quad_proj[][9] = {
2058 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2059 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2060 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2061 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2064 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2065 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2066 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2067 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2068 D3DDECL_END()
2070 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2071 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2072 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2073 D3DDECL_END()
2074 } };
2076 /* use asymmetric matrix to test loading */
2077 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2079 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2080 IDirect3DPixelShader9 *pixel_shader = NULL;
2081 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
2082 D3DLOCKED_RECT locked_rect;
2084 generate_bumpmap_textures(device);
2086 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2087 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2088 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2089 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2090 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2092 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2093 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2095 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2096 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2098 for(i=0; i<2; i++)
2100 if(i)
2102 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2103 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2106 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2107 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2108 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2109 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2111 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2112 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2113 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2114 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2116 hr = IDirect3DDevice9_BeginScene(device);
2117 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2119 if(!i)
2120 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2121 else
2122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2123 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2125 hr = IDirect3DDevice9_EndScene(device);
2126 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2128 color = getPixelColor(device, 320-32, 240);
2129 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2130 color = getPixelColor(device, 320+32, 240);
2131 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2132 color = getPixelColor(device, 320, 240-32);
2133 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2134 color = getPixelColor(device, 320, 240+32);
2135 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2138 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2140 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2141 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2142 IDirect3DPixelShader9_Release(pixel_shader);
2144 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2145 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2146 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2149 /* clean up */
2150 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2151 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2153 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2154 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2156 for(i=0; i<2; i++)
2158 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2159 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2160 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2161 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2162 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2163 IDirect3DTexture9_Release(texture);
2166 /* Test double texbem */
2167 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2168 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2169 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2170 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2171 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2172 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2173 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2174 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2176 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2177 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2178 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2179 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2181 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2182 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2184 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2185 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2186 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2187 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2188 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2189 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2192 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2193 #define tex 0x00ff0000
2194 #define tex1 0x0000ff00
2195 #define origin 0x000000ff
2196 static const DWORD pixel_data[] = {
2197 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2198 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2199 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2200 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2201 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2202 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2203 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2204 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2206 #undef tex1
2207 #undef tex2
2208 #undef origin
2210 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2211 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2212 for(i = 0; i < 8; i++) {
2213 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2215 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2216 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2219 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2220 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2221 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2222 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2223 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2225 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2226 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2227 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2228 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2229 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2230 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2232 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2233 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2234 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2236 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2238 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2240 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2243 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2244 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2245 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2247 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2249 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2251 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2254 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2256 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2258 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2260 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2262 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2264 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2266 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2267 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2268 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2269 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2271 hr = IDirect3DDevice9_BeginScene(device);
2272 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2273 if(SUCCEEDED(hr)) {
2274 static const float double_quad[] = {
2275 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2276 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2277 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2278 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2282 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2283 hr = IDirect3DDevice9_EndScene(device);
2284 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2286 color = getPixelColor(device, 320, 240);
2287 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2289 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2290 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2291 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2293 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2294 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2295 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2296 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2297 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2298 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2300 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2301 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2303 IDirect3DPixelShader9_Release(pixel_shader);
2304 IDirect3DTexture9_Release(texture);
2305 IDirect3DTexture9_Release(texture1);
2306 IDirect3DTexture9_Release(texture2);
2309 static void z_range_test(IDirect3DDevice9 *device)
2311 const struct vertex quad[] =
2313 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2314 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2315 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2316 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2318 const struct vertex quad2[] =
2320 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2321 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2322 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2323 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2326 const struct tvertex quad3[] =
2328 { 0, 240, 1.1f, 1.0, 0xffffff00},
2329 { 0, 480, 1.1f, 1.0, 0xffffff00},
2330 { 640, 240, -1.1f, 1.0, 0xffffff00},
2331 { 640, 480, -1.1f, 1.0, 0xffffff00},
2333 const struct tvertex quad4[] =
2335 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2336 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2337 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2338 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2340 HRESULT hr;
2341 DWORD color;
2342 IDirect3DVertexShader9 *shader;
2343 IDirect3DVertexDeclaration9 *decl;
2344 D3DCAPS9 caps;
2345 const DWORD shader_code[] = {
2346 0xfffe0101, /* vs_1_1 */
2347 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2348 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2349 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2350 0x0000ffff /* end */
2352 static const D3DVERTEXELEMENT9 decl_elements[] = {
2353 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2354 D3DDECL_END()
2357 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2359 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2360 * then call Present. Then clear the color buffer to make sure it has some defined content
2361 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2362 * by the depth value.
2364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2366 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2367 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2368 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2369 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2372 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2374 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2376 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2378 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2379 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2380 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2382 hr = IDirect3DDevice9_BeginScene(device);
2383 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2384 if(hr == D3D_OK)
2386 /* Test the untransformed vertex path */
2387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2388 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2390 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2392 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2394 /* Test the transformed vertex path */
2395 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2396 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2401 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2403 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2405 hr = IDirect3DDevice9_EndScene(device);
2406 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2409 /* Do not test the exact corner pixels, but go pretty close to them */
2411 /* Clipped because z > 1.0 */
2412 color = getPixelColor(device, 28, 238);
2413 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2414 color = getPixelColor(device, 28, 241);
2415 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2417 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2419 else
2421 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2424 /* Not clipped, > z buffer clear value(0.75) */
2425 color = getPixelColor(device, 31, 238);
2426 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2427 color = getPixelColor(device, 31, 241);
2428 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2429 color = getPixelColor(device, 100, 238);
2430 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2431 color = getPixelColor(device, 100, 241);
2432 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2434 /* Not clipped, < z buffer clear value */
2435 color = getPixelColor(device, 104, 238);
2436 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2437 color = getPixelColor(device, 104, 241);
2438 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2439 color = getPixelColor(device, 318, 238);
2440 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2441 color = getPixelColor(device, 318, 241);
2442 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2444 /* Clipped because z < 0.0 */
2445 color = getPixelColor(device, 321, 238);
2446 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2447 color = getPixelColor(device, 321, 241);
2448 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2450 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2452 else
2454 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2457 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2458 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2460 /* Test the shader path */
2461 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2462 skip("Vertex shaders not supported\n");
2463 goto out;
2465 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2466 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2467 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2468 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2472 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2473 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2474 IDirect3DDevice9_SetVertexShader(device, shader);
2475 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2477 hr = IDirect3DDevice9_BeginScene(device);
2478 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2479 if(hr == D3D_OK)
2481 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2482 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2483 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2485 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2487 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2488 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2490 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2492 hr = IDirect3DDevice9_EndScene(device);
2493 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2496 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2497 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2498 IDirect3DDevice9_SetVertexShader(device, NULL);
2499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2501 IDirect3DVertexDeclaration9_Release(decl);
2502 IDirect3DVertexShader9_Release(shader);
2504 /* Z < 1.0 */
2505 color = getPixelColor(device, 28, 238);
2506 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2508 /* 1.0 < z < 0.75 */
2509 color = getPixelColor(device, 31, 238);
2510 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2511 color = getPixelColor(device, 100, 238);
2512 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2514 /* 0.75 < z < 0.0 */
2515 color = getPixelColor(device, 104, 238);
2516 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2517 color = getPixelColor(device, 318, 238);
2518 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2520 /* 0.0 < z */
2521 color = getPixelColor(device, 321, 238);
2522 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2524 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2525 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2527 out:
2528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2531 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2533 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2536 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2538 D3DSURFACE_DESC desc;
2539 D3DLOCKED_RECT l;
2540 HRESULT hr;
2541 unsigned int x, y;
2542 DWORD *mem;
2544 memset(&desc, 0, sizeof(desc));
2545 memset(&l, 0, sizeof(l));
2546 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2547 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2548 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2549 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2550 if(FAILED(hr)) return;
2552 for(y = 0; y < desc.Height; y++)
2554 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2555 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2557 mem[x] = color;
2560 hr = IDirect3DSurface9_UnlockRect(surface);
2561 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2564 /* This tests a variety of possible StretchRect() situations */
2565 static void stretchrect_test(IDirect3DDevice9 *device)
2567 HRESULT hr;
2568 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2569 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2570 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2571 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2572 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2573 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2574 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2575 IDirect3DSurface9 *orig_rt = NULL;
2576 IDirect3DSurface9 *backbuffer = NULL;
2577 DWORD color;
2579 RECT src_rect64 = {0, 0, 64, 64};
2580 RECT src_rect64_flipy = {0, 64, 64, 0};
2581 RECT dst_rect64 = {0, 0, 64, 64};
2582 RECT dst_rect64_flipy = {0, 64, 64, 0};
2584 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2585 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2586 if(!orig_rt) {
2587 goto out;
2590 /* Create our temporary surfaces in system memory */
2591 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2592 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2593 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2594 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2596 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2597 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2598 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2599 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2600 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2601 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2602 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2604 /* Create render target surfaces */
2605 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2606 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2607 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2608 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2609 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2610 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2611 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2612 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2614 /* Create render target textures */
2615 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2616 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2617 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2618 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2619 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2620 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2621 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2622 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2623 if (tex_rt32) {
2624 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2625 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2627 if (tex_rt64) {
2628 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2629 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2631 if (tex_rt_dest64) {
2632 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2633 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2635 if (tex_rt_dest64) {
2636 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2637 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2640 /* Create regular textures in D3DPOOL_DEFAULT */
2641 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2642 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2643 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2644 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2645 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2646 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2647 if (tex32) {
2648 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2649 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2651 if (tex64) {
2652 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2653 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2655 if (tex_dest64) {
2656 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2657 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2660 /*********************************************************************
2661 * Tests for when the source parameter is an offscreen plain surface *
2662 *********************************************************************/
2664 /* Fill the offscreen 64x64 surface with green */
2665 if (surf_offscreen64)
2666 fill_surface(surf_offscreen64, 0xff00ff00);
2668 /* offscreenplain ==> offscreenplain, same size */
2669 if(surf_offscreen64 && surf_offscreen_dest64) {
2670 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2671 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2673 if (hr == D3D_OK) {
2674 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2675 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2678 /* Blit without scaling */
2679 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2680 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2682 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2683 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2684 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2686 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2687 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2688 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2691 /* offscreenplain ==> rendertarget texture, same size */
2692 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2693 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2694 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2696 /* We can't lock rendertarget textures, so copy to our temp surface first */
2697 if (hr == D3D_OK) {
2698 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2699 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2702 if (hr == D3D_OK) {
2703 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2704 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2707 /* Blit without scaling */
2708 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2709 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2711 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2712 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2713 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2715 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2716 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2717 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720 /* offscreenplain ==> rendertarget surface, same size */
2721 if(surf_offscreen64 && surf_rt_dest64) {
2722 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2723 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2725 if (hr == D3D_OK) {
2726 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2727 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2730 /* Blit without scaling */
2731 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2732 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2734 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2735 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2736 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2738 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2739 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2740 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2743 /* offscreenplain ==> texture, same size (should fail) */
2744 if(surf_offscreen64 && surf_tex_dest64) {
2745 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2746 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2749 /* Fill the smaller offscreen surface with red */
2750 fill_surface(surf_offscreen32, 0xffff0000);
2752 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2753 if(surf_offscreen32 && surf_offscreen64) {
2754 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2755 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2758 /* offscreenplain ==> rendertarget texture, scaling */
2759 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2760 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2761 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763 /* We can't lock rendertarget textures, so copy to our temp surface first */
2764 if (hr == D3D_OK) {
2765 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2766 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2769 if (hr == D3D_OK) {
2770 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2771 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2775 /* offscreenplain ==> rendertarget surface, scaling */
2776 if(surf_offscreen32 && surf_rt_dest64) {
2777 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2778 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2780 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2781 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2784 /* offscreenplain ==> texture, scaling (should fail) */
2785 if(surf_offscreen32 && surf_tex_dest64) {
2786 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2787 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2790 /************************************************************
2791 * Tests for when the source parameter is a regular texture *
2792 ************************************************************/
2794 /* Fill the surface of the regular texture with blue */
2795 if (surf_tex64 && surf_temp64) {
2796 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2797 fill_surface(surf_temp64, 0xff0000ff);
2798 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2799 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2802 /* texture ==> offscreenplain, same size */
2803 if(surf_tex64 && surf_offscreen64) {
2804 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2805 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2808 /* texture ==> rendertarget texture, same size */
2809 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2810 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2811 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2813 /* We can't lock rendertarget textures, so copy to our temp surface first */
2814 if (hr == D3D_OK) {
2815 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2816 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2819 if (hr == D3D_OK) {
2820 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2821 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2824 /* Blit without scaling */
2825 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2826 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2828 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2829 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2830 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2832 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2833 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2834 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837 /* texture ==> rendertarget surface, same size */
2838 if(surf_tex64 && surf_rt_dest64) {
2839 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2840 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2842 if (hr == D3D_OK) {
2843 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2844 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2847 /* Blit without scaling */
2848 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2849 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2851 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2852 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2853 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2855 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2856 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2857 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860 /* texture ==> texture, same size (should fail) */
2861 if(surf_tex64 && surf_tex_dest64) {
2862 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2863 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2866 /* Fill the surface of the smaller regular texture with red */
2867 if (surf_tex32 && surf_temp32) {
2868 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2869 fill_surface(surf_temp32, 0xffff0000);
2870 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2871 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2874 /* texture ==> offscreenplain, scaling (should fail) */
2875 if(surf_tex32 && surf_offscreen64) {
2876 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2877 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2880 /* texture ==> rendertarget texture, scaling */
2881 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2882 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2883 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2885 /* We can't lock rendertarget textures, so copy to our temp surface first */
2886 if (hr == D3D_OK) {
2887 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2888 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2891 if (hr == D3D_OK) {
2892 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2893 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2897 /* texture ==> rendertarget surface, scaling */
2898 if(surf_tex32 && surf_rt_dest64) {
2899 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2900 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2902 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2903 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2906 /* texture ==> texture, scaling (should fail) */
2907 if(surf_tex32 && surf_tex_dest64) {
2908 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2909 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2912 /*****************************************************************
2913 * Tests for when the source parameter is a rendertarget texture *
2914 *****************************************************************/
2916 /* Fill the surface of the rendertarget texture with white */
2917 if (surf_tex_rt64 && surf_temp64) {
2918 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2919 fill_surface(surf_temp64, 0xffffffff);
2920 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2921 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2924 /* rendertarget texture ==> offscreenplain, same size */
2925 if(surf_tex_rt64 && surf_offscreen64) {
2926 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2927 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2930 /* rendertarget texture ==> rendertarget texture, same size */
2931 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2932 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2933 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2935 /* We can't lock rendertarget textures, so copy to our temp surface first */
2936 if (hr == D3D_OK) {
2937 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2938 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2941 if (hr == D3D_OK) {
2942 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2943 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2946 /* Blit without scaling */
2947 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2948 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2950 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2951 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2952 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2954 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2955 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2956 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2959 /* rendertarget texture ==> rendertarget surface, same size */
2960 if(surf_tex_rt64 && surf_rt_dest64) {
2961 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2962 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2964 if (hr == D3D_OK) {
2965 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2966 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2969 /* Blit without scaling */
2970 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2971 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2974 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2975 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2978 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2979 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2982 /* rendertarget texture ==> texture, same size (should fail) */
2983 if(surf_tex_rt64 && surf_tex_dest64) {
2984 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2985 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2988 /* Fill the surface of the smaller rendertarget texture with red */
2989 if (surf_tex_rt32 && surf_temp32) {
2990 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2991 fill_surface(surf_temp32, 0xffff0000);
2992 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2993 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2996 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2997 if(surf_tex_rt32 && surf_offscreen64) {
2998 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2999 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3002 /* rendertarget texture ==> rendertarget texture, scaling */
3003 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3004 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3005 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3007 /* We can't lock rendertarget textures, so copy to our temp surface first */
3008 if (hr == D3D_OK) {
3009 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3010 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3013 if (hr == D3D_OK) {
3014 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3015 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3019 /* rendertarget texture ==> rendertarget surface, scaling */
3020 if(surf_tex_rt32 && surf_rt_dest64) {
3021 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3022 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3024 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3025 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3028 /* rendertarget texture ==> texture, scaling (should fail) */
3029 if(surf_tex_rt32 && surf_tex_dest64) {
3030 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3031 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3034 /*****************************************************************
3035 * Tests for when the source parameter is a rendertarget surface *
3036 *****************************************************************/
3038 /* Fill the surface of the rendertarget surface with black */
3039 if (surf_rt64)
3040 fill_surface(surf_rt64, 0xff000000);
3042 /* rendertarget texture ==> offscreenplain, same size */
3043 if(surf_rt64 && surf_offscreen64) {
3044 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3045 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3048 /* rendertarget surface ==> rendertarget texture, same size */
3049 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3050 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3051 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3053 /* We can't lock rendertarget textures, so copy to our temp surface first */
3054 if (hr == D3D_OK) {
3055 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3056 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3059 if (hr == D3D_OK) {
3060 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3061 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3064 /* Blit without scaling */
3065 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3066 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3068 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3069 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3070 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3072 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3073 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3074 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3077 /* rendertarget surface ==> rendertarget surface, same size */
3078 if(surf_rt64 && surf_rt_dest64) {
3079 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3080 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082 if (hr == D3D_OK) {
3083 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3084 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3087 /* Blit without scaling */
3088 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3089 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3092 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3093 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3096 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3097 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3100 /* rendertarget surface ==> texture, same size (should fail) */
3101 if(surf_rt64 && surf_tex_dest64) {
3102 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3103 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3106 /* Fill the surface of the smaller rendertarget texture with red */
3107 if (surf_rt32)
3108 fill_surface(surf_rt32, 0xffff0000);
3110 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3111 if(surf_rt32 && surf_offscreen64) {
3112 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3113 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3116 /* rendertarget surface ==> rendertarget texture, scaling */
3117 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3118 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3119 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3121 /* We can't lock rendertarget textures, so copy to our temp surface first */
3122 if (hr == D3D_OK) {
3123 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3124 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3127 if (hr == D3D_OK) {
3128 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3129 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3133 /* rendertarget surface ==> rendertarget surface, scaling */
3134 if(surf_rt32 && surf_rt_dest64) {
3135 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3136 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3138 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3139 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3142 /* rendertarget surface ==> texture, scaling (should fail) */
3143 if(surf_rt32 && surf_tex_dest64) {
3144 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3145 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3148 /* backbuffer ==> surface tests (no scaling) */
3149 if(backbuffer && surf_tex_rt_dest640_480)
3151 RECT src_rect = {0, 0, 640, 480};
3152 RECT src_rect_flipy = {0, 480, 640, 0};
3153 RECT dst_rect = {0, 0, 640, 480};
3154 RECT dst_rect_flipy = {0, 480, 640, 0};
3156 /* Blit with NULL rectangles */
3157 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3158 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3160 /* Blit without scaling */
3161 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3162 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3164 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3165 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3166 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3168 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3169 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3170 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3173 /* TODO: Test format conversions */
3176 out:
3177 /* Clean up */
3178 if (backbuffer)
3179 IDirect3DSurface9_Release(backbuffer);
3180 if (surf_rt32)
3181 IDirect3DSurface9_Release(surf_rt32);
3182 if (surf_rt64)
3183 IDirect3DSurface9_Release(surf_rt64);
3184 if (surf_rt_dest64)
3185 IDirect3DSurface9_Release(surf_rt_dest64);
3186 if (surf_temp32)
3187 IDirect3DSurface9_Release(surf_temp32);
3188 if (surf_temp64)
3189 IDirect3DSurface9_Release(surf_temp64);
3190 if (surf_offscreen32)
3191 IDirect3DSurface9_Release(surf_offscreen32);
3192 if (surf_offscreen64)
3193 IDirect3DSurface9_Release(surf_offscreen64);
3194 if (surf_offscreen_dest64)
3195 IDirect3DSurface9_Release(surf_offscreen_dest64);
3197 if (tex_rt32) {
3198 if (surf_tex_rt32)
3199 IDirect3DSurface9_Release(surf_tex_rt32);
3200 IDirect3DTexture9_Release(tex_rt32);
3202 if (tex_rt64) {
3203 if (surf_tex_rt64)
3204 IDirect3DSurface9_Release(surf_tex_rt64);
3205 IDirect3DTexture9_Release(tex_rt64);
3207 if (tex_rt_dest64) {
3208 if (surf_tex_rt_dest64)
3209 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3210 IDirect3DTexture9_Release(tex_rt_dest64);
3212 if (tex_rt_dest640_480) {
3213 if (surf_tex_rt_dest640_480)
3214 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3215 IDirect3DTexture9_Release(tex_rt_dest640_480);
3217 if (tex32) {
3218 if (surf_tex32)
3219 IDirect3DSurface9_Release(surf_tex32);
3220 IDirect3DTexture9_Release(tex32);
3222 if (tex64) {
3223 if (surf_tex64)
3224 IDirect3DSurface9_Release(surf_tex64);
3225 IDirect3DTexture9_Release(tex64);
3227 if (tex_dest64) {
3228 if (surf_tex_dest64)
3229 IDirect3DSurface9_Release(surf_tex_dest64);
3230 IDirect3DTexture9_Release(tex_dest64);
3233 if (orig_rt) {
3234 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3235 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3236 IDirect3DSurface9_Release(orig_rt);
3240 static void maxmip_test(IDirect3DDevice9 *device)
3242 IDirect3DTexture9 *texture = NULL;
3243 IDirect3DSurface9 *surface = NULL;
3244 HRESULT hr;
3245 DWORD color;
3246 static const struct
3248 struct
3250 float x, y, z;
3251 float s, t;
3253 v[4];
3255 quads[] =
3258 {-1.0, -1.0, 0.0, 0.0, 0.0},
3259 {-1.0, 0.0, 0.0, 0.0, 1.0},
3260 { 0.0, -1.0, 0.0, 1.0, 0.0},
3261 { 0.0, 0.0, 0.0, 1.0, 1.0},
3264 { 0.0, -1.0, 0.0, 0.0, 0.0},
3265 { 0.0, 0.0, 0.0, 0.0, 1.0},
3266 { 1.0, -1.0, 0.0, 1.0, 0.0},
3267 { 1.0, 0.0, 0.0, 1.0, 1.0},
3270 { 0.0, 0.0, 0.0, 0.0, 0.0},
3271 { 0.0, 1.0, 0.0, 0.0, 1.0},
3272 { 1.0, 0.0, 0.0, 1.0, 0.0},
3273 { 1.0, 1.0, 0.0, 1.0, 1.0},
3276 {-1.0, 0.0, 0.0, 0.0, 0.0},
3277 {-1.0, 1.0, 0.0, 0.0, 1.0},
3278 { 0.0, 0.0, 0.0, 1.0, 0.0},
3279 { 0.0, 1.0, 0.0, 1.0, 1.0},
3283 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3284 &texture, NULL);
3285 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3286 if(!texture)
3288 skip("Failed to create test texture\n");
3289 return;
3292 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3293 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3294 fill_surface(surface, 0xffff0000);
3295 IDirect3DSurface9_Release(surface);
3296 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3297 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3298 fill_surface(surface, 0xff00ff00);
3299 IDirect3DSurface9_Release(surface);
3300 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3301 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3302 fill_surface(surface, 0xff0000ff);
3303 IDirect3DSurface9_Release(surface);
3305 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3306 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3307 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3310 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3311 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3314 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3316 hr = IDirect3DDevice9_BeginScene(device);
3317 if(SUCCEEDED(hr))
3319 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3320 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3322 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3324 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3325 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3329 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3330 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3332 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3334 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3335 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3337 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3338 hr = IDirect3DDevice9_EndScene(device);
3339 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3342 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3343 color = getPixelColor(device, 160, 360);
3344 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3345 color = getPixelColor(device, 480, 360);
3346 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3347 color = getPixelColor(device, 480, 120);
3348 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3349 color = getPixelColor(device, 160, 120);
3350 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3351 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3352 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3354 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3355 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3357 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3358 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3360 hr = IDirect3DDevice9_BeginScene(device);
3361 if(SUCCEEDED(hr))
3363 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3364 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3366 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3368 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3369 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3370 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3371 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3373 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3374 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3376 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3378 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3379 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3381 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3382 hr = IDirect3DDevice9_EndScene(device);
3383 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3386 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3387 * level 3 (> levels in texture) samples from the highest level in the
3388 * texture (level 2). */
3389 color = getPixelColor(device, 160, 360);
3390 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3391 color = getPixelColor(device, 480, 360);
3392 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3393 color = getPixelColor(device, 480, 120);
3394 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3395 color = getPixelColor(device, 160, 120);
3396 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3397 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3398 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3400 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3401 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3403 hr = IDirect3DDevice9_BeginScene(device);
3404 if(SUCCEEDED(hr))
3406 DWORD ret;
3408 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3409 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3410 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3411 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3412 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3413 ret = IDirect3DTexture9_SetLOD(texture, 1);
3414 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3416 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3418 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3419 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3420 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3421 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3422 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3423 ret = IDirect3DTexture9_SetLOD(texture, 2);
3424 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3425 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3426 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3428 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3429 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3430 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3431 ret = IDirect3DTexture9_SetLOD(texture, 1);
3432 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3434 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3436 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3437 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3438 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3439 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3440 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3441 ret = IDirect3DTexture9_SetLOD(texture, 1);
3442 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3444 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3445 hr = IDirect3DDevice9_EndScene(device);
3446 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3449 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3450 * level 3 (> levels in texture) samples from the highest level in the
3451 * texture (level 2). */
3452 color = getPixelColor(device, 160, 360);
3453 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3454 color = getPixelColor(device, 480, 360);
3455 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3456 color = getPixelColor(device, 480, 120);
3457 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3458 color = getPixelColor(device, 160, 120);
3459 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3461 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3462 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3464 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3465 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3466 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3468 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3470 IDirect3DTexture9_Release(texture);
3473 static void release_buffer_test(IDirect3DDevice9 *device)
3475 IDirect3DVertexBuffer9 *vb = NULL;
3476 IDirect3DIndexBuffer9 *ib = NULL;
3477 HRESULT hr;
3478 BYTE *data;
3479 LONG ref;
3481 static const struct vertex quad[] = {
3482 {-1.0, -1.0, 0.1, 0xffff0000},
3483 {-1.0, 1.0, 0.1, 0xffff0000},
3484 { 1.0, 1.0, 0.1, 0xffff0000},
3486 {-1.0, -1.0, 0.1, 0xff00ff00},
3487 {-1.0, 1.0, 0.1, 0xff00ff00},
3488 { 1.0, 1.0, 0.1, 0xff00ff00}
3490 short indices[] = {3, 4, 5};
3492 /* Index and vertex buffers should always be creatable */
3493 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3494 D3DPOOL_MANAGED, &vb, NULL);
3495 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3496 if(!vb) {
3497 skip("Failed to create a vertex buffer\n");
3498 return;
3500 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3502 if(!ib) {
3503 skip("Failed to create an index buffer\n");
3504 return;
3507 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3508 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3509 memcpy(data, quad, sizeof(quad));
3510 hr = IDirect3DVertexBuffer9_Unlock(vb);
3511 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3513 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3514 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3515 memcpy(data, indices, sizeof(indices));
3516 hr = IDirect3DIndexBuffer9_Unlock(ib);
3517 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3519 hr = IDirect3DDevice9_SetIndices(device, ib);
3520 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3521 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3522 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3523 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3524 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3526 /* Now destroy the bound index buffer and draw again */
3527 ref = IDirect3DIndexBuffer9_Release(ib);
3528 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3530 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3531 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3533 hr = IDirect3DDevice9_BeginScene(device);
3534 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3535 if(SUCCEEDED(hr))
3537 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3538 * making assumptions about the indices or vertices
3540 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3541 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3542 hr = IDirect3DDevice9_EndScene(device);
3543 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3546 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3547 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3549 hr = IDirect3DDevice9_SetIndices(device, NULL);
3550 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3551 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3552 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3554 /* Index buffer was already destroyed as part of the test */
3555 IDirect3DVertexBuffer9_Release(vb);
3558 static void float_texture_test(IDirect3DDevice9 *device)
3560 IDirect3D9 *d3d = NULL;
3561 HRESULT hr;
3562 IDirect3DTexture9 *texture = NULL;
3563 D3DLOCKED_RECT lr;
3564 float *data;
3565 DWORD color;
3566 float quad[] = {
3567 -1.0, -1.0, 0.1, 0.0, 0.0,
3568 -1.0, 1.0, 0.1, 0.0, 1.0,
3569 1.0, -1.0, 0.1, 1.0, 0.0,
3570 1.0, 1.0, 0.1, 1.0, 1.0,
3573 memset(&lr, 0, sizeof(lr));
3574 IDirect3DDevice9_GetDirect3D(device, &d3d);
3575 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3576 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3577 skip("D3DFMT_R32F textures not supported\n");
3578 goto out;
3581 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3582 D3DPOOL_MANAGED, &texture, NULL);
3583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3584 if(!texture) {
3585 skip("Failed to create R32F texture\n");
3586 goto out;
3589 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3590 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3591 data = lr.pBits;
3592 *data = 0.0;
3593 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3594 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3596 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3597 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3599 hr = IDirect3DDevice9_BeginScene(device);
3600 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3601 if(SUCCEEDED(hr))
3603 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3604 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3609 hr = IDirect3DDevice9_EndScene(device);
3610 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3612 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3613 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3615 color = getPixelColor(device, 240, 320);
3616 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3619 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3621 out:
3622 if(texture) IDirect3DTexture9_Release(texture);
3623 IDirect3D9_Release(d3d);
3626 static void g16r16_texture_test(IDirect3DDevice9 *device)
3628 IDirect3D9 *d3d = NULL;
3629 HRESULT hr;
3630 IDirect3DTexture9 *texture = NULL;
3631 D3DLOCKED_RECT lr;
3632 DWORD *data;
3633 DWORD color;
3634 float quad[] = {
3635 -1.0, -1.0, 0.1, 0.0, 0.0,
3636 -1.0, 1.0, 0.1, 0.0, 1.0,
3637 1.0, -1.0, 0.1, 1.0, 0.0,
3638 1.0, 1.0, 0.1, 1.0, 1.0,
3641 memset(&lr, 0, sizeof(lr));
3642 IDirect3DDevice9_GetDirect3D(device, &d3d);
3643 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3644 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3645 skip("D3DFMT_G16R16 textures not supported\n");
3646 goto out;
3649 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3650 D3DPOOL_MANAGED, &texture, NULL);
3651 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3652 if(!texture) {
3653 skip("Failed to create D3DFMT_G16R16 texture\n");
3654 goto out;
3657 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3658 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3659 data = lr.pBits;
3660 *data = 0x0f00f000;
3661 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3662 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3664 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3665 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3667 hr = IDirect3DDevice9_BeginScene(device);
3668 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3669 if(SUCCEEDED(hr))
3671 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3675 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3677 hr = IDirect3DDevice9_EndScene(device);
3678 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3680 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3681 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3683 color = getPixelColor(device, 240, 320);
3684 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3685 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3687 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3688 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3690 out:
3691 if(texture) IDirect3DTexture9_Release(texture);
3692 IDirect3D9_Release(d3d);
3695 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3697 HRESULT hr;
3698 IDirect3D9 *d3d;
3699 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3700 D3DCAPS9 caps;
3701 IDirect3DTexture9 *texture = NULL;
3702 IDirect3DVolumeTexture9 *volume = NULL;
3703 unsigned int x, y, z;
3704 D3DLOCKED_RECT lr;
3705 D3DLOCKED_BOX lb;
3706 DWORD color;
3707 UINT w, h;
3708 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3709 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3710 0.0, 1.0, 0.0, 0.0,
3711 0.0, 0.0, 1.0, 0.0,
3712 0.0, 0.0, 0.0, 1.0};
3713 static const D3DVERTEXELEMENT9 decl_elements[] = {
3714 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3715 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3716 D3DDECL_END()
3718 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3719 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3720 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3721 D3DDECL_END()
3723 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3724 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3725 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3726 D3DDECL_END()
3728 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3729 0x00, 0xff, 0x00, 0x00,
3730 0x00, 0x00, 0x00, 0x00,
3731 0x00, 0x00, 0x00, 0x00};
3733 memset(&lr, 0, sizeof(lr));
3734 memset(&lb, 0, sizeof(lb));
3735 IDirect3DDevice9_GetDirect3D(device, &d3d);
3736 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3737 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3738 fmt = D3DFMT_A16B16G16R16;
3740 IDirect3D9_Release(d3d);
3742 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3743 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3744 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3745 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3746 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3747 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3748 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3749 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3750 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3752 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3753 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3754 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3755 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3757 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3758 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3759 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3760 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3761 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3762 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3763 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3764 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3765 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3767 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3768 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3769 w = min(1024, caps.MaxTextureWidth);
3770 h = min(1024, caps.MaxTextureHeight);
3771 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3772 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3774 if(!texture) {
3775 skip("Failed to create the test texture\n");
3776 return;
3779 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3780 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3781 * 1.0 in red and green for the x and y coords
3783 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3784 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3785 for(y = 0; y < h; y++) {
3786 for(x = 0; x < w; x++) {
3787 double r_f = (double) y / (double) h;
3788 double g_f = (double) x / (double) w;
3789 if(fmt == D3DFMT_A16B16G16R16) {
3790 unsigned short r, g;
3791 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3792 r = (unsigned short) (r_f * 65536.0);
3793 g = (unsigned short) (g_f * 65536.0);
3794 dst[0] = r;
3795 dst[1] = g;
3796 dst[2] = 0;
3797 dst[3] = 65535;
3798 } else {
3799 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3800 unsigned char r = (unsigned char) (r_f * 255.0);
3801 unsigned char g = (unsigned char) (g_f * 255.0);
3802 dst[0] = 0;
3803 dst[1] = g;
3804 dst[2] = r;
3805 dst[3] = 255;
3809 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3810 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3811 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3812 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3814 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3815 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3816 hr = IDirect3DDevice9_BeginScene(device);
3817 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3818 if(SUCCEEDED(hr))
3820 float quad1[] = {
3821 -1.0, -1.0, 0.1, 1.0, 1.0,
3822 -1.0, 0.0, 0.1, 1.0, 1.0,
3823 0.0, -1.0, 0.1, 1.0, 1.0,
3824 0.0, 0.0, 0.1, 1.0, 1.0,
3826 float quad2[] = {
3827 -1.0, 0.0, 0.1, 1.0, 1.0,
3828 -1.0, 1.0, 0.1, 1.0, 1.0,
3829 0.0, 0.0, 0.1, 1.0, 1.0,
3830 0.0, 1.0, 0.1, 1.0, 1.0,
3832 float quad3[] = {
3833 0.0, 0.0, 0.1, 0.5, 0.5,
3834 0.0, 1.0, 0.1, 0.5, 0.5,
3835 1.0, 0.0, 0.1, 0.5, 0.5,
3836 1.0, 1.0, 0.1, 0.5, 0.5,
3838 float quad4[] = {
3839 320, 480, 0.1, 1.0, 0.0, 1.0,
3840 320, 240, 0.1, 1.0, 0.0, 1.0,
3841 640, 480, 0.1, 1.0, 0.0, 1.0,
3842 640, 240, 0.1, 1.0, 0.0, 1.0,
3844 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3845 0.0, 0.0, 0.0, 0.0,
3846 0.0, 0.0, 0.0, 0.0,
3847 0.0, 0.0, 0.0, 0.0};
3849 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3850 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3851 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3853 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3855 /* What happens with transforms enabled? */
3856 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3857 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3858 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3859 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3861 /* What happens if 4 coords are used, but only 2 given ?*/
3862 mat[8] = 1.0;
3863 mat[13] = 1.0;
3864 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3865 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3866 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3867 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3868 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3869 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3871 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3872 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3873 * due to the coords in the vertices. (turns out red, indeed)
3875 memset(mat, 0, sizeof(mat));
3876 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3878 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3879 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3880 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3881 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3883 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3885 hr = IDirect3DDevice9_EndScene(device);
3886 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3888 color = getPixelColor(device, 160, 360);
3889 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3890 color = getPixelColor(device, 160, 120);
3891 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3892 color = getPixelColor(device, 480, 120);
3893 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3894 color = getPixelColor(device, 480, 360);
3895 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3896 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3897 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3899 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3900 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3902 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3903 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3904 hr = IDirect3DDevice9_BeginScene(device);
3905 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3906 if(SUCCEEDED(hr))
3908 float quad1[] = {
3909 -1.0, -1.0, 0.1, 0.8, 0.2,
3910 -1.0, 0.0, 0.1, 0.8, 0.2,
3911 0.0, -1.0, 0.1, 0.8, 0.2,
3912 0.0, 0.0, 0.1, 0.8, 0.2,
3914 float quad2[] = {
3915 -1.0, 0.0, 0.1, 0.5, 1.0,
3916 -1.0, 1.0, 0.1, 0.5, 1.0,
3917 0.0, 0.0, 0.1, 0.5, 1.0,
3918 0.0, 1.0, 0.1, 0.5, 1.0,
3920 float quad3[] = {
3921 0.0, 0.0, 0.1, 0.5, 1.0,
3922 0.0, 1.0, 0.1, 0.5, 1.0,
3923 1.0, 0.0, 0.1, 0.5, 1.0,
3924 1.0, 1.0, 0.1, 0.5, 1.0,
3926 float quad4[] = {
3927 0.0, -1.0, 0.1, 0.8, 0.2,
3928 0.0, 0.0, 0.1, 0.8, 0.2,
3929 1.0, -1.0, 0.1, 0.8, 0.2,
3930 1.0, 0.0, 0.1, 0.8, 0.2,
3932 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3933 0.0, 0.0, 0.0, 0.0,
3934 0.0, 1.0, 0.0, 0.0,
3935 0.0, 0.0, 0.0, 0.0};
3937 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3939 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3940 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3941 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3942 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3947 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3948 * it behaves like COUNT2 because normal textures require 2 coords
3950 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3951 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3953 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3955 /* Just to be sure, the same as quad2 above */
3956 memset(mat, 0, sizeof(mat));
3957 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3958 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3959 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3960 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3962 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3964 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3965 * used? And what happens to the first?
3967 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3968 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3970 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3972 hr = IDirect3DDevice9_EndScene(device);
3973 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3975 color = getPixelColor(device, 160, 360);
3976 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3977 color = getPixelColor(device, 160, 120);
3978 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3979 color = getPixelColor(device, 480, 120);
3980 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3981 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3982 color = getPixelColor(device, 480, 360);
3983 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3984 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3985 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3986 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3988 IDirect3DTexture9_Release(texture);
3990 /* Test projected textures, without any fancy matrices */
3991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3992 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3993 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3994 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3995 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3996 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3997 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3998 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4000 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4001 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4002 for(x = 0; x < 4; x++) {
4003 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4005 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4006 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4007 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4008 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4010 hr = IDirect3DDevice9_BeginScene(device);
4011 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4012 if(SUCCEEDED(hr))
4014 const float proj_quads[] = {
4015 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4016 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4017 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4018 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4019 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4020 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4021 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4022 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4025 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4026 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4027 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
4028 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4030 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
4031 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4032 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
4033 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4035 hr = IDirect3DDevice9_EndScene(device);
4036 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4039 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4040 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4041 IDirect3DTexture9_Release(texture);
4043 color = getPixelColor(device, 158, 118);
4044 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
4045 color = getPixelColor(device, 162, 118);
4046 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
4047 color = getPixelColor(device, 158, 122);
4048 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
4049 color = getPixelColor(device, 162, 122);
4050 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
4052 color = getPixelColor(device, 158, 178);
4053 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
4054 color = getPixelColor(device, 162, 178);
4055 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
4056 color = getPixelColor(device, 158, 182);
4057 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
4058 color = getPixelColor(device, 162, 182);
4059 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
4061 color = getPixelColor(device, 318, 118);
4062 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
4063 color = getPixelColor(device, 322, 118);
4064 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
4065 color = getPixelColor(device, 318, 122);
4066 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
4067 color = getPixelColor(device, 322, 122);
4068 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
4070 color = getPixelColor(device, 318, 178);
4071 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
4072 color = getPixelColor(device, 322, 178);
4073 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
4074 color = getPixelColor(device, 318, 182);
4075 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
4076 color = getPixelColor(device, 322, 182);
4077 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
4079 color = getPixelColor(device, 238, 298);
4080 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
4081 color = getPixelColor(device, 242, 298);
4082 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
4083 color = getPixelColor(device, 238, 302);
4084 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
4085 color = getPixelColor(device, 242, 302);
4086 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
4088 color = getPixelColor(device, 238, 388);
4089 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
4090 color = getPixelColor(device, 242, 388);
4091 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4092 color = getPixelColor(device, 238, 392);
4093 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
4094 color = getPixelColor(device, 242, 392);
4095 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
4097 color = getPixelColor(device, 478, 298);
4098 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
4099 color = getPixelColor(device, 482, 298);
4100 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
4101 color = getPixelColor(device, 478, 302);
4102 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
4103 color = getPixelColor(device, 482, 302);
4104 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
4106 color = getPixelColor(device, 478, 388);
4107 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4108 color = getPixelColor(device, 482, 388);
4109 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
4110 color = getPixelColor(device, 478, 392);
4111 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
4112 color = getPixelColor(device, 482, 392);
4113 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
4115 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4116 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4118 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4119 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4120 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4121 * Thus watch out if sampling from texels between 0 and 1.
4123 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4124 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4125 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4126 if(!volume) {
4127 skip("Failed to create a volume texture\n");
4128 goto out;
4131 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4132 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4133 for(z = 0; z < 32; z++) {
4134 for(y = 0; y < 32; y++) {
4135 for(x = 0; x < 32; x++) {
4136 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4137 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4138 float r_f = (float) x / 31.0;
4139 float g_f = (float) y / 31.0;
4140 float b_f = (float) z / 31.0;
4142 if(fmt == D3DFMT_A16B16G16R16) {
4143 unsigned short *mem_s = mem;
4144 mem_s[0] = r_f * 65535.0;
4145 mem_s[1] = g_f * 65535.0;
4146 mem_s[2] = b_f * 65535.0;
4147 mem_s[3] = 65535;
4148 } else {
4149 unsigned char *mem_c = mem;
4150 mem_c[0] = b_f * 255.0;
4151 mem_c[1] = g_f * 255.0;
4152 mem_c[2] = r_f * 255.0;
4153 mem_c[3] = 255;
4158 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4159 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4161 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4162 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4164 hr = IDirect3DDevice9_BeginScene(device);
4165 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4166 if(SUCCEEDED(hr))
4168 float quad1[] = {
4169 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4170 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4171 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4172 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4174 float quad2[] = {
4175 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4176 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4177 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4178 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4180 float quad3[] = {
4181 0.0, 0.0, 0.1, 0.0, 0.0,
4182 0.0, 1.0, 0.1, 0.0, 0.0,
4183 1.0, 0.0, 0.1, 0.0, 0.0,
4184 1.0, 1.0, 0.1, 0.0, 0.0
4186 float quad4[] = {
4187 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4188 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4189 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4190 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4192 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4193 0.0, 0.0, 1.0, 0.0,
4194 0.0, 1.0, 0.0, 0.0,
4195 0.0, 0.0, 0.0, 1.0};
4196 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4197 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4199 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4200 * values
4202 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4203 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4204 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4206 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4207 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4209 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4210 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4211 * otherwise the w will be missing(blue).
4212 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4213 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4215 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4216 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4218 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4220 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4221 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4222 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4223 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4224 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4225 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4226 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4228 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4230 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4231 * disable. ATI extends it up to the amount of values needed for the volume texture
4233 memset(mat, 0, sizeof(mat));
4234 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4235 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4236 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4237 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4238 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4241 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4243 hr = IDirect3DDevice9_EndScene(device);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4247 color = getPixelColor(device, 160, 360);
4248 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4249 color = getPixelColor(device, 160, 120);
4250 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4251 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4252 color = getPixelColor(device, 480, 120);
4253 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4254 color = getPixelColor(device, 480, 360);
4255 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4257 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4258 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4260 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4261 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4262 hr = IDirect3DDevice9_BeginScene(device);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4264 if(SUCCEEDED(hr))
4266 float quad1[] = {
4267 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4268 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4269 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4270 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4272 float quad2[] = {
4273 -1.0, 0.0, 0.1,
4274 -1.0, 1.0, 0.1,
4275 0.0, 0.0, 0.1,
4276 0.0, 1.0, 0.1,
4278 float quad3[] = {
4279 0.0, 0.0, 0.1, 1.0,
4280 0.0, 1.0, 0.1, 1.0,
4281 1.0, 0.0, 0.1, 1.0,
4282 1.0, 1.0, 0.1, 1.0
4284 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4285 0.0, 0.0, 0.0, 0.0,
4286 0.0, 0.0, 0.0, 0.0,
4287 0.0, 1.0, 0.0, 0.0};
4288 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4289 1.0, 0.0, 0.0, 0.0,
4290 0.0, 1.0, 0.0, 0.0,
4291 0.0, 0.0, 1.0, 0.0};
4292 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4293 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4295 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4296 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4297 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4298 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4299 * 4th *input* coordinate.
4301 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4302 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4303 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4304 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4306 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4308 /* None passed */
4309 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4311 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4312 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4314 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4316 /* 4 used, 1 passed */
4317 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4318 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4319 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4320 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4324 hr = IDirect3DDevice9_EndScene(device);
4325 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4327 color = getPixelColor(device, 160, 360);
4328 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4329 color = getPixelColor(device, 160, 120);
4330 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4331 color = getPixelColor(device, 480, 120);
4332 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4333 /* Quad4: unused */
4335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4336 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4338 IDirect3DVolumeTexture9_Release(volume);
4340 out:
4341 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4342 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4343 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4344 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4345 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4346 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4347 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4348 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4349 IDirect3DVertexDeclaration9_Release(decl);
4350 IDirect3DVertexDeclaration9_Release(decl2);
4351 IDirect3DVertexDeclaration9_Release(decl3);
4354 static void texdepth_test(IDirect3DDevice9 *device)
4356 IDirect3DPixelShader9 *shader;
4357 HRESULT hr;
4358 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4359 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4360 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4361 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4362 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4363 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4364 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4365 DWORD shader_code[] = {
4366 0xffff0104, /* ps_1_4 */
4367 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4368 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4369 0x0000fffd, /* phase */
4370 0x00000057, 0x800f0005, /* texdepth r5 */
4371 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4372 0x0000ffff /* end */
4374 DWORD color;
4375 float vertex[] = {
4376 -1.0, -1.0, 0.0,
4377 1.0, -1.0, 1.0,
4378 -1.0, 1.0, 0.0,
4379 1.0, 1.0, 1.0
4382 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4383 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4388 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4392 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4393 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4394 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4396 /* Fill the depth buffer with a gradient */
4397 hr = IDirect3DDevice9_BeginScene(device);
4398 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4399 if(SUCCEEDED(hr))
4401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4402 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4403 hr = IDirect3DDevice9_EndScene(device);
4404 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4407 /* Now perform the actual tests. Same geometry, but with the shader */
4408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4409 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4411 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4412 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4413 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4415 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4416 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4417 hr = IDirect3DDevice9_BeginScene(device);
4418 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4419 if(SUCCEEDED(hr))
4421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4422 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4424 hr = IDirect3DDevice9_EndScene(device);
4425 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4428 color = getPixelColor(device, 158, 240);
4429 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4430 color = getPixelColor(device, 162, 240);
4431 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4433 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4434 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4436 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4437 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4439 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4440 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4441 hr = IDirect3DDevice9_BeginScene(device);
4442 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4443 if(SUCCEEDED(hr))
4445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4446 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4448 hr = IDirect3DDevice9_EndScene(device);
4449 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4452 color = getPixelColor(device, 318, 240);
4453 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4454 color = getPixelColor(device, 322, 240);
4455 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4457 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4458 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4461 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4463 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4464 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4465 hr = IDirect3DDevice9_BeginScene(device);
4466 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4467 if(SUCCEEDED(hr))
4469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4470 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4472 hr = IDirect3DDevice9_EndScene(device);
4473 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4476 color = getPixelColor(device, 1, 240);
4477 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4479 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4480 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4482 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4483 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4485 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4486 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4487 hr = IDirect3DDevice9_BeginScene(device);
4488 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4489 if(SUCCEEDED(hr))
4491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4492 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4494 hr = IDirect3DDevice9_EndScene(device);
4495 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4497 color = getPixelColor(device, 318, 240);
4498 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4499 color = getPixelColor(device, 322, 240);
4500 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4502 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4503 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4505 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4506 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4508 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4509 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4510 hr = IDirect3DDevice9_BeginScene(device);
4511 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4512 if(SUCCEEDED(hr))
4514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4515 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4517 hr = IDirect3DDevice9_EndScene(device);
4518 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4521 color = getPixelColor(device, 1, 240);
4522 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4524 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4525 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4527 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4528 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4530 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4531 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4532 hr = IDirect3DDevice9_BeginScene(device);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4534 if(SUCCEEDED(hr))
4536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4537 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4539 hr = IDirect3DDevice9_EndScene(device);
4540 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4543 color = getPixelColor(device, 638, 240);
4544 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4546 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4550 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4552 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4553 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4554 hr = IDirect3DDevice9_BeginScene(device);
4555 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4556 if(SUCCEEDED(hr))
4558 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4559 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4561 hr = IDirect3DDevice9_EndScene(device);
4562 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4565 color = getPixelColor(device, 638, 240);
4566 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4569 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4571 /* Cleanup */
4572 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4573 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4574 IDirect3DPixelShader9_Release(shader);
4576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4577 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4579 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4582 static void texkill_test(IDirect3DDevice9 *device)
4584 IDirect3DPixelShader9 *shader;
4585 HRESULT hr;
4586 DWORD color;
4588 const float vertex[] = {
4589 /* bottom top right left */
4590 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4591 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4592 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4593 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4596 DWORD shader_code_11[] = {
4597 0xffff0101, /* ps_1_1 */
4598 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4599 0x00000041, 0xb00f0000, /* texkill t0 */
4600 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4601 0x0000ffff /* end */
4603 DWORD shader_code_20[] = {
4604 0xffff0200, /* ps_2_0 */
4605 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4606 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4607 0x01000041, 0xb00f0000, /* texkill t0 */
4608 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4609 0x0000ffff /* end */
4612 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4613 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4614 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4615 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4617 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4618 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4619 hr = IDirect3DDevice9_BeginScene(device);
4620 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4621 if(SUCCEEDED(hr))
4623 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4624 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4626 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4627 hr = IDirect3DDevice9_EndScene(device);
4628 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4630 color = getPixelColor(device, 63, 46);
4631 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4632 color = getPixelColor(device, 66, 46);
4633 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4634 color = getPixelColor(device, 63, 49);
4635 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4636 color = getPixelColor(device, 66, 49);
4637 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4639 color = getPixelColor(device, 578, 46);
4640 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4641 color = getPixelColor(device, 575, 46);
4642 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4643 color = getPixelColor(device, 578, 49);
4644 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4645 color = getPixelColor(device, 575, 49);
4646 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4648 color = getPixelColor(device, 63, 430);
4649 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4650 color = getPixelColor(device, 63, 433);
4651 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4652 color = getPixelColor(device, 66, 433);
4653 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4654 color = getPixelColor(device, 66, 430);
4655 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4657 color = getPixelColor(device, 578, 430);
4658 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4659 color = getPixelColor(device, 578, 433);
4660 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4661 color = getPixelColor(device, 575, 433);
4662 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4663 color = getPixelColor(device, 575, 430);
4664 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4666 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4669 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4670 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4671 IDirect3DPixelShader9_Release(shader);
4673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4675 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4676 if(FAILED(hr)) {
4677 skip("Failed to create 2.0 test shader, most likely not supported\n");
4678 return;
4681 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4682 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4683 hr = IDirect3DDevice9_BeginScene(device);
4684 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4685 if(SUCCEEDED(hr))
4687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4688 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4689 hr = IDirect3DDevice9_EndScene(device);
4690 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4693 color = getPixelColor(device, 63, 46);
4694 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4695 color = getPixelColor(device, 66, 46);
4696 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4697 color = getPixelColor(device, 63, 49);
4698 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4699 color = getPixelColor(device, 66, 49);
4700 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4702 color = getPixelColor(device, 578, 46);
4703 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4704 color = getPixelColor(device, 575, 46);
4705 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4706 color = getPixelColor(device, 578, 49);
4707 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4708 color = getPixelColor(device, 575, 49);
4709 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4711 color = getPixelColor(device, 63, 430);
4712 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4713 color = getPixelColor(device, 63, 433);
4714 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4715 color = getPixelColor(device, 66, 433);
4716 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4717 color = getPixelColor(device, 66, 430);
4718 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4720 color = getPixelColor(device, 578, 430);
4721 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4722 color = getPixelColor(device, 578, 433);
4723 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4724 color = getPixelColor(device, 575, 433);
4725 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4726 color = getPixelColor(device, 575, 430);
4727 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4729 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4730 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4732 /* Cleanup */
4733 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4734 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4735 IDirect3DPixelShader9_Release(shader);
4738 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4740 IDirect3D9 *d3d9;
4741 HRESULT hr;
4742 IDirect3DTexture9 *texture;
4743 IDirect3DPixelShader9 *shader;
4744 IDirect3DPixelShader9 *shader2;
4745 D3DLOCKED_RECT lr;
4746 DWORD color;
4747 DWORD shader_code[] = {
4748 0xffff0101, /* ps_1_1 */
4749 0x00000042, 0xb00f0000, /* tex t0 */
4750 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4751 0x0000ffff /* end */
4753 DWORD shader_code2[] = {
4754 0xffff0101, /* ps_1_1 */
4755 0x00000042, 0xb00f0000, /* tex t0 */
4756 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4757 0x0000ffff /* end */
4760 float quad[] = {
4761 -1.0, -1.0, 0.1, 0.5, 0.5,
4762 1.0, -1.0, 0.1, 0.5, 0.5,
4763 -1.0, 1.0, 0.1, 0.5, 0.5,
4764 1.0, 1.0, 0.1, 0.5, 0.5,
4767 memset(&lr, 0, sizeof(lr));
4768 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4769 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4770 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4771 IDirect3D9_Release(d3d9);
4772 if(FAILED(hr)) {
4773 skip("No D3DFMT_X8L8V8U8 support\n");
4774 return;
4777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4780 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4781 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4782 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4783 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4784 *((DWORD *) lr.pBits) = 0x11ca3141;
4785 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4786 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4788 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4789 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4790 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4791 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4793 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4795 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4797 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4800 hr = IDirect3DDevice9_BeginScene(device);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4802 if(SUCCEEDED(hr))
4804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4805 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4807 hr = IDirect3DDevice9_EndScene(device);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4810 color = getPixelColor(device, 578, 430);
4811 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4812 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4813 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4816 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4817 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4818 hr = IDirect3DDevice9_BeginScene(device);
4819 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4820 if(SUCCEEDED(hr))
4822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4823 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4825 hr = IDirect3DDevice9_EndScene(device);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4828 color = getPixelColor(device, 578, 430);
4829 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4831 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4833 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4835 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4837 IDirect3DPixelShader9_Release(shader);
4838 IDirect3DPixelShader9_Release(shader2);
4839 IDirect3DTexture9_Release(texture);
4842 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4844 HRESULT hr;
4845 IDirect3D9 *d3d;
4846 IDirect3DTexture9 *texture = NULL;
4847 IDirect3DSurface9 *surface;
4848 DWORD color;
4849 const RECT r1 = {256, 256, 512, 512};
4850 const RECT r2 = {512, 256, 768, 512};
4851 const RECT r3 = {256, 512, 512, 768};
4852 const RECT r4 = {512, 512, 768, 768};
4853 unsigned int x, y;
4854 D3DLOCKED_RECT lr;
4855 memset(&lr, 0, sizeof(lr));
4857 IDirect3DDevice9_GetDirect3D(device, &d3d);
4858 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4859 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4860 skip("No autogenmipmap support\n");
4861 IDirect3D9_Release(d3d);
4862 return;
4864 IDirect3D9_Release(d3d);
4866 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4867 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4869 /* Make the mipmap big, so that a smaller mipmap is used
4871 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4872 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4873 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4875 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4876 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4877 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4878 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4879 for(y = 0; y < 1024; y++) {
4880 for(x = 0; x < 1024; x++) {
4881 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4882 POINT pt;
4884 pt.x = x;
4885 pt.y = y;
4886 if(PtInRect(&r1, pt)) {
4887 *dst = 0xffff0000;
4888 } else if(PtInRect(&r2, pt)) {
4889 *dst = 0xff00ff00;
4890 } else if(PtInRect(&r3, pt)) {
4891 *dst = 0xff0000ff;
4892 } else if(PtInRect(&r4, pt)) {
4893 *dst = 0xff000000;
4894 } else {
4895 *dst = 0xffffffff;
4899 hr = IDirect3DSurface9_UnlockRect(surface);
4900 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4901 IDirect3DSurface9_Release(surface);
4903 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4904 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4905 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4906 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4908 hr = IDirect3DDevice9_BeginScene(device);
4909 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4910 if(SUCCEEDED(hr)) {
4911 const float quad[] = {
4912 -0.5, -0.5, 0.1, 0.0, 0.0,
4913 -0.5, 0.5, 0.1, 0.0, 1.0,
4914 0.5, -0.5, 0.1, 1.0, 0.0,
4915 0.5, 0.5, 0.1, 1.0, 1.0
4918 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4919 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4920 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4921 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4922 hr = IDirect3DDevice9_EndScene(device);
4923 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4925 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4926 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4927 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4928 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4929 IDirect3DTexture9_Release(texture);
4931 color = getPixelColor(device, 200, 200);
4932 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4933 color = getPixelColor(device, 280, 200);
4934 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4935 color = getPixelColor(device, 360, 200);
4936 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4937 color = getPixelColor(device, 440, 200);
4938 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4939 color = getPixelColor(device, 200, 270);
4940 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4941 color = getPixelColor(device, 280, 270);
4942 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4943 color = getPixelColor(device, 360, 270);
4944 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4945 color = getPixelColor(device, 440, 270);
4946 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4947 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4951 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4953 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4954 IDirect3DVertexDeclaration9 *decl;
4955 HRESULT hr;
4956 DWORD color;
4957 DWORD shader_code_11[] = {
4958 0xfffe0101, /* vs_1_1 */
4959 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4960 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4961 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4962 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4963 0x0000ffff /* end */
4965 DWORD shader_code_11_2[] = {
4966 0xfffe0101, /* vs_1_1 */
4967 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4968 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4969 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4970 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4971 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4972 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4973 0x0000ffff /* end */
4975 DWORD shader_code_20[] = {
4976 0xfffe0200, /* vs_2_0 */
4977 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4978 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4979 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4980 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4981 0x0000ffff /* end */
4983 DWORD shader_code_20_2[] = {
4984 0xfffe0200, /* vs_2_0 */
4985 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4986 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4987 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4988 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4989 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4990 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4991 0x0000ffff /* end */
4993 static const D3DVERTEXELEMENT9 decl_elements[] = {
4994 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4995 D3DDECL_END()
4997 float quad1[] = {
4998 -1.0, -1.0, 0.1,
4999 0.0, -1.0, 0.1,
5000 -1.0, 0.0, 0.1,
5001 0.0, 0.0, 0.1
5003 float quad2[] = {
5004 0.0, -1.0, 0.1,
5005 1.0, -1.0, 0.1,
5006 0.0, 0.0, 0.1,
5007 1.0, 0.0, 0.1
5009 float quad3[] = {
5010 0.0, 0.0, 0.1,
5011 1.0, 0.0, 0.1,
5012 0.0, 1.0, 0.1,
5013 1.0, 1.0, 0.1
5015 float quad4[] = {
5016 -1.0, 0.0, 0.1,
5017 0.0, 0.0, 0.1,
5018 -1.0, 1.0, 0.1,
5019 0.0, 1.0, 0.1
5021 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5022 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5024 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5025 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5027 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5028 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5029 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5031 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5032 if(FAILED(hr)) shader_20 = NULL;
5033 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5034 if(FAILED(hr)) shader_20_2 = NULL;
5035 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5036 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5038 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5039 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5040 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5041 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5042 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5043 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5045 hr = IDirect3DDevice9_BeginScene(device);
5046 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5047 if(SUCCEEDED(hr))
5049 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5050 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5051 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5052 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5054 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5055 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5057 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5059 if(shader_20) {
5060 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5063 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5066 if(shader_20_2) {
5067 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5068 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5070 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5073 hr = IDirect3DDevice9_EndScene(device);
5074 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5077 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5078 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5079 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5080 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5082 color = getPixelColor(device, 160, 360);
5083 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5084 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5085 color = getPixelColor(device, 480, 360);
5086 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5087 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5088 if(shader_20) {
5089 color = getPixelColor(device, 480, 120);
5090 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5091 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5093 if(shader_20_2) {
5094 color = getPixelColor(device, 160, 120);
5095 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5096 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5098 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5099 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5101 IDirect3DVertexDeclaration9_Release(decl);
5102 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5103 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5104 IDirect3DVertexShader9_Release(shader_11_2);
5105 IDirect3DVertexShader9_Release(shader_11);
5108 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5110 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5111 HRESULT hr;
5112 DWORD color;
5113 DWORD shader_code_11[] = {
5114 0xffff0101, /* ps_1_1 */
5115 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5116 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5117 0x0000ffff /* end */
5119 DWORD shader_code_12[] = {
5120 0xffff0102, /* ps_1_2 */
5121 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5122 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5123 0x0000ffff /* end */
5125 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5126 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5127 * During development of this test, 1.3 shaders were verified too
5129 DWORD shader_code_14[] = {
5130 0xffff0104, /* ps_1_4 */
5131 /* Try to make one constant local. It gets clamped too, although the binary contains
5132 * the bigger numbers
5134 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5135 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5136 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5137 0x0000ffff /* end */
5139 DWORD shader_code_20[] = {
5140 0xffff0200, /* ps_2_0 */
5141 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5142 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5143 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5144 0x0000ffff /* end */
5146 float quad1[] = {
5147 -1.0, -1.0, 0.1,
5148 0.0, -1.0, 0.1,
5149 -1.0, 0.0, 0.1,
5150 0.0, 0.0, 0.1
5152 float quad2[] = {
5153 0.0, -1.0, 0.1,
5154 1.0, -1.0, 0.1,
5155 0.0, 0.0, 0.1,
5156 1.0, 0.0, 0.1
5158 float quad3[] = {
5159 0.0, 0.0, 0.1,
5160 1.0, 0.0, 0.1,
5161 0.0, 1.0, 0.1,
5162 1.0, 1.0, 0.1
5164 float quad4[] = {
5165 -1.0, 0.0, 0.1,
5166 0.0, 0.0, 0.1,
5167 -1.0, 1.0, 0.1,
5168 0.0, 1.0, 0.1
5170 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5171 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5173 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5174 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5176 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5177 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5178 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5179 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5180 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5181 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5182 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5183 if(FAILED(hr)) shader_20 = NULL;
5185 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5186 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5187 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5188 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5189 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5190 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5192 hr = IDirect3DDevice9_BeginScene(device);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5194 if(SUCCEEDED(hr))
5196 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5197 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5199 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5201 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5202 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5204 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5206 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5207 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5209 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5211 if(shader_20) {
5212 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5213 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5215 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5218 hr = IDirect3DDevice9_EndScene(device);
5219 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5221 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5222 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5224 color = getPixelColor(device, 160, 360);
5225 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5226 "quad 1 has color %08x, expected 0x00808000\n", color);
5227 color = getPixelColor(device, 480, 360);
5228 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5229 "quad 2 has color %08x, expected 0x00808000\n", color);
5230 color = getPixelColor(device, 480, 120);
5231 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5232 "quad 3 has color %08x, expected 0x00808000\n", color);
5233 if(shader_20) {
5234 color = getPixelColor(device, 160, 120);
5235 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5236 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5241 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5242 IDirect3DPixelShader9_Release(shader_14);
5243 IDirect3DPixelShader9_Release(shader_12);
5244 IDirect3DPixelShader9_Release(shader_11);
5247 static void dp2add_ps_test(IDirect3DDevice9 *device)
5249 IDirect3DPixelShader9 *shader_dp2add = NULL;
5250 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5251 HRESULT hr;
5252 DWORD color;
5254 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5255 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5256 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5257 * r0 first.
5258 * The result here for the r,g,b components should be roughly 0.5:
5259 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5260 static const DWORD shader_code_dp2add[] = {
5261 0xffff0200, /* ps_2_0 */
5262 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5264 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5265 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5267 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5268 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5269 0x0000ffff /* end */
5272 /* Test the _sat modifier, too. Result here should be:
5273 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5274 * _SAT: ==> 1.0
5275 * ADD: (1.0 + -0.5) = 0.5
5277 static const DWORD shader_code_dp2add_sat[] = {
5278 0xffff0200, /* ps_2_0 */
5279 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5281 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5282 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5283 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5285 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5286 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5287 0x0000ffff /* end */
5290 const float quad[] = {
5291 -1.0, -1.0, 0.1,
5292 1.0, -1.0, 0.1,
5293 -1.0, 1.0, 0.1,
5294 1.0, 1.0, 0.1
5298 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5299 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5301 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5304 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5305 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5307 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5308 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5310 if (shader_dp2add) {
5312 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5313 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5315 hr = IDirect3DDevice9_BeginScene(device);
5316 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5317 if(SUCCEEDED(hr))
5319 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5320 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5322 hr = IDirect3DDevice9_EndScene(device);
5323 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5326 color = getPixelColor(device, 360, 240);
5327 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5328 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5330 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5331 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5333 IDirect3DPixelShader9_Release(shader_dp2add);
5334 } else {
5335 skip("dp2add shader creation failed\n");
5338 if (shader_dp2add_sat) {
5340 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5343 hr = IDirect3DDevice9_BeginScene(device);
5344 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5345 if(SUCCEEDED(hr))
5347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5348 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5350 hr = IDirect3DDevice9_EndScene(device);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5354 color = getPixelColor(device, 360, 240);
5355 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5356 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5359 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5361 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5362 } else {
5363 skip("dp2add shader creation failed\n");
5366 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5370 static void cnd_test(IDirect3DDevice9 *device)
5372 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5373 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5374 HRESULT hr;
5375 DWORD color;
5376 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5377 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5378 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5380 DWORD shader_code_11[] = {
5381 0xffff0101, /* ps_1_1 */
5382 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5383 0x00000040, 0xb00f0000, /* texcoord t0 */
5384 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5385 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5386 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5387 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5388 0x0000ffff /* end */
5390 DWORD shader_code_12[] = {
5391 0xffff0102, /* ps_1_2 */
5392 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5393 0x00000040, 0xb00f0000, /* texcoord t0 */
5394 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5395 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5396 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5397 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5398 0x0000ffff /* end */
5400 DWORD shader_code_13[] = {
5401 0xffff0103, /* ps_1_3 */
5402 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5403 0x00000040, 0xb00f0000, /* texcoord t0 */
5404 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5405 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5406 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5407 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5408 0x0000ffff /* end */
5410 DWORD shader_code_14[] = {
5411 0xffff0104, /* ps_1_3 */
5412 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5413 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5414 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5415 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5416 0x0000ffff /* end */
5419 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5420 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5421 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5422 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5423 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5424 * well enough.
5426 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5427 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5428 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5429 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5431 DWORD shader_code_11_coissue[] = {
5432 0xffff0101, /* ps_1_1 */
5433 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5434 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5435 0x00000040, 0xb00f0000, /* texcoord t0 */
5436 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5437 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5438 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5439 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5440 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5441 /* 0x40000000 = D3DSI_COISSUE */
5442 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5443 0x0000ffff /* end */
5445 DWORD shader_code_12_coissue[] = {
5446 0xffff0102, /* ps_1_2 */
5447 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5448 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5449 0x00000040, 0xb00f0000, /* texcoord t0 */
5450 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5451 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5452 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5453 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5454 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5455 /* 0x40000000 = D3DSI_COISSUE */
5456 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5457 0x0000ffff /* end */
5459 DWORD shader_code_13_coissue[] = {
5460 0xffff0103, /* ps_1_3 */
5461 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5462 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5463 0x00000040, 0xb00f0000, /* texcoord t0 */
5464 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5465 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5466 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5467 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5468 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5469 /* 0x40000000 = D3DSI_COISSUE */
5470 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5471 0x0000ffff /* end */
5473 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5474 * compare against 0.5
5476 DWORD shader_code_14_coissue[] = {
5477 0xffff0104, /* ps_1_4 */
5478 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5479 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5480 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5481 /* 0x40000000 = D3DSI_COISSUE */
5482 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5483 0x0000ffff /* end */
5485 float quad1[] = {
5486 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5487 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5488 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5489 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5491 float quad2[] = {
5492 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5493 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5494 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5495 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5497 float quad3[] = {
5498 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5499 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5500 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5501 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5503 float quad4[] = {
5504 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5505 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5506 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5507 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5509 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5510 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5511 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5512 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5514 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5515 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5517 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5519 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5521 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5523 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5524 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5525 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5526 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5527 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5529 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5530 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5531 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5532 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5534 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5535 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5536 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5537 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5538 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5539 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5541 hr = IDirect3DDevice9_BeginScene(device);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5543 if(SUCCEEDED(hr))
5545 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5548 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5550 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5551 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5553 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5555 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5556 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5558 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5560 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5561 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5563 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5565 hr = IDirect3DDevice9_EndScene(device);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5569 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5570 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5572 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5573 color = getPixelColor(device, 158, 118);
5574 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5575 color = getPixelColor(device, 162, 118);
5576 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5577 color = getPixelColor(device, 158, 122);
5578 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5579 color = getPixelColor(device, 162, 122);
5580 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5582 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5583 color = getPixelColor(device, 158, 358);
5584 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5585 color = getPixelColor(device, 162, 358);
5586 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5587 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5588 color = getPixelColor(device, 158, 362);
5589 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5590 color = getPixelColor(device, 162, 362);
5591 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5592 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5594 /* 1.2 shader */
5595 color = getPixelColor(device, 478, 358);
5596 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5597 color = getPixelColor(device, 482, 358);
5598 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5599 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5600 color = getPixelColor(device, 478, 362);
5601 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5602 color = getPixelColor(device, 482, 362);
5603 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5604 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5606 /* 1.3 shader */
5607 color = getPixelColor(device, 478, 118);
5608 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5609 color = getPixelColor(device, 482, 118);
5610 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5611 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5612 color = getPixelColor(device, 478, 122);
5613 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5614 color = getPixelColor(device, 482, 122);
5615 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5616 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5621 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5622 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5623 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5625 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5626 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5628 hr = IDirect3DDevice9_BeginScene(device);
5629 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5630 if(SUCCEEDED(hr))
5632 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5635 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5637 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5640 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5642 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5643 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5645 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5647 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5650 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5652 hr = IDirect3DDevice9_EndScene(device);
5653 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5656 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5657 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5659 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5660 * that we swapped the values in c1 and c2 to make the other tests return some color
5662 color = getPixelColor(device, 158, 118);
5663 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5664 color = getPixelColor(device, 162, 118);
5665 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5666 color = getPixelColor(device, 158, 122);
5667 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5668 color = getPixelColor(device, 162, 122);
5669 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5671 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5672 * (The Win7 nvidia driver always selects c2)
5674 color = getPixelColor(device, 158, 358);
5675 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5676 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5677 color = getPixelColor(device, 162, 358);
5678 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5679 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5680 color = getPixelColor(device, 158, 362);
5681 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5682 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5683 color = getPixelColor(device, 162, 362);
5684 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5685 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5687 /* 1.2 shader */
5688 color = getPixelColor(device, 478, 358);
5689 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5690 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5691 color = getPixelColor(device, 482, 358);
5692 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5693 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5694 color = getPixelColor(device, 478, 362);
5695 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5696 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5697 color = getPixelColor(device, 482, 362);
5698 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5699 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5701 /* 1.3 shader */
5702 color = getPixelColor(device, 478, 118);
5703 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5704 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5705 color = getPixelColor(device, 482, 118);
5706 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5707 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5708 color = getPixelColor(device, 478, 122);
5709 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5710 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5711 color = getPixelColor(device, 482, 122);
5712 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5713 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5715 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5716 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5718 IDirect3DPixelShader9_Release(shader_14_coissue);
5719 IDirect3DPixelShader9_Release(shader_13_coissue);
5720 IDirect3DPixelShader9_Release(shader_12_coissue);
5721 IDirect3DPixelShader9_Release(shader_11_coissue);
5722 IDirect3DPixelShader9_Release(shader_14);
5723 IDirect3DPixelShader9_Release(shader_13);
5724 IDirect3DPixelShader9_Release(shader_12);
5725 IDirect3DPixelShader9_Release(shader_11);
5728 static void nested_loop_test(IDirect3DDevice9 *device) {
5729 const DWORD shader_code[] = {
5730 0xffff0300, /* ps_3_0 */
5731 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5732 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5733 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5734 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5735 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5736 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5737 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5738 0x0000001d, /* endloop */
5739 0x0000001d, /* endloop */
5740 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5741 0x0000ffff /* end */
5743 const DWORD vshader_code[] = {
5744 0xfffe0300, /* vs_3_0 */
5745 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5746 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5747 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5748 0x0000ffff /* end */
5750 IDirect3DPixelShader9 *shader;
5751 IDirect3DVertexShader9 *vshader;
5752 HRESULT hr;
5753 DWORD color;
5754 const float quad[] = {
5755 -1.0, -1.0, 0.1,
5756 1.0, -1.0, 0.1,
5757 -1.0, 1.0, 0.1,
5758 1.0, 1.0, 0.1
5761 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5762 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5763 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5764 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5765 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5766 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5767 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5768 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5769 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5770 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5774 hr = IDirect3DDevice9_BeginScene(device);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5776 if(SUCCEEDED(hr))
5778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5779 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780 hr = IDirect3DDevice9_EndScene(device);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5784 color = getPixelColor(device, 360, 240);
5785 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5786 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5791 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5792 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5793 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5795 IDirect3DPixelShader9_Release(shader);
5796 IDirect3DVertexShader9_Release(vshader);
5799 struct varying_test_struct
5801 const DWORD *shader_code;
5802 IDirect3DPixelShader9 *shader;
5803 DWORD color, color_rhw;
5804 const char *name;
5805 BOOL todo, todo_rhw;
5808 struct hugeVertex
5810 float pos_x, pos_y, pos_z, rhw;
5811 float weight_1, weight_2, weight_3, weight_4;
5812 float index_1, index_2, index_3, index_4;
5813 float normal_1, normal_2, normal_3, normal_4;
5814 float fog_1, fog_2, fog_3, fog_4;
5815 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5816 float tangent_1, tangent_2, tangent_3, tangent_4;
5817 float binormal_1, binormal_2, binormal_3, binormal_4;
5818 float depth_1, depth_2, depth_3, depth_4;
5819 DWORD diffuse, specular;
5822 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5823 /* dcl_position: fails to compile */
5824 const DWORD blendweight_code[] = {
5825 0xffff0300, /* ps_3_0 */
5826 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5827 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5828 0x0000ffff /* end */
5830 const DWORD blendindices_code[] = {
5831 0xffff0300, /* ps_3_0 */
5832 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5833 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5834 0x0000ffff /* end */
5836 const DWORD normal_code[] = {
5837 0xffff0300, /* ps_3_0 */
5838 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5839 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5840 0x0000ffff /* end */
5842 /* psize: fails? */
5843 const DWORD texcoord0_code[] = {
5844 0xffff0300, /* ps_3_0 */
5845 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5846 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5847 0x0000ffff /* end */
5849 const DWORD tangent_code[] = {
5850 0xffff0300, /* ps_3_0 */
5851 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5852 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5853 0x0000ffff /* end */
5855 const DWORD binormal_code[] = {
5856 0xffff0300, /* ps_3_0 */
5857 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5858 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5859 0x0000ffff /* end */
5861 /* tessfactor: fails */
5862 /* positiont: fails */
5863 const DWORD color_code[] = {
5864 0xffff0300, /* ps_3_0 */
5865 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5866 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5867 0x0000ffff /* end */
5869 const DWORD fog_code[] = {
5870 0xffff0300, /* ps_3_0 */
5871 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5872 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5873 0x0000ffff /* end */
5875 const DWORD depth_code[] = {
5876 0xffff0300, /* ps_3_0 */
5877 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5878 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5879 0x0000ffff /* end */
5881 const DWORD specular_code[] = {
5882 0xffff0300, /* ps_3_0 */
5883 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5884 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5885 0x0000ffff /* end */
5887 /* sample: fails */
5889 struct varying_test_struct tests[] = {
5890 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5891 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5892 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5893 /* Why does dx not forward the texcoord? */
5894 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5895 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5896 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5897 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5898 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5899 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5900 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5902 /* Declare a monster vertex type :-) */
5903 static const D3DVERTEXELEMENT9 decl_elements[] = {
5904 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5905 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5906 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5907 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5908 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5909 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5910 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5911 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5912 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5913 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5914 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5915 D3DDECL_END()
5917 struct hugeVertex data[4] = {
5919 -1.0, -1.0, 0.1, 1.0,
5920 0.1, 0.1, 0.1, 0.1,
5921 0.2, 0.2, 0.2, 0.2,
5922 0.3, 0.3, 0.3, 0.3,
5923 0.4, 0.4, 0.4, 0.4,
5924 0.50, 0.55, 0.55, 0.55,
5925 0.6, 0.6, 0.6, 0.7,
5926 0.7, 0.7, 0.7, 0.6,
5927 0.8, 0.8, 0.8, 0.8,
5928 0xe6e6e6e6, /* 0.9 * 256 */
5929 0x224488ff /* Nothing special */
5932 1.0, -1.0, 0.1, 1.0,
5933 0.1, 0.1, 0.1, 0.1,
5934 0.2, 0.2, 0.2, 0.2,
5935 0.3, 0.3, 0.3, 0.3,
5936 0.4, 0.4, 0.4, 0.4,
5937 0.50, 0.55, 0.55, 0.55,
5938 0.6, 0.6, 0.6, 0.7,
5939 0.7, 0.7, 0.7, 0.6,
5940 0.8, 0.8, 0.8, 0.8,
5941 0xe6e6e6e6, /* 0.9 * 256 */
5942 0x224488ff /* Nothing special */
5945 -1.0, 1.0, 0.1, 1.0,
5946 0.1, 0.1, 0.1, 0.1,
5947 0.2, 0.2, 0.2, 0.2,
5948 0.3, 0.3, 0.3, 0.3,
5949 0.4, 0.4, 0.4, 0.4,
5950 0.50, 0.55, 0.55, 0.55,
5951 0.6, 0.6, 0.6, 0.7,
5952 0.7, 0.7, 0.7, 0.6,
5953 0.8, 0.8, 0.8, 0.8,
5954 0xe6e6e6e6, /* 0.9 * 256 */
5955 0x224488ff /* Nothing special */
5958 1.0, 1.0, 0.1, 1.0,
5959 0.1, 0.1, 0.1, 0.1,
5960 0.2, 0.2, 0.2, 0.2,
5961 0.3, 0.3, 0.3, 0.3,
5962 0.4, 0.4, 0.4, 0.4,
5963 0.50, 0.55, 0.55, 0.55,
5964 0.6, 0.6, 0.6, 0.7,
5965 0.7, 0.7, 0.7, 0.6,
5966 0.8, 0.8, 0.8, 0.8,
5967 0xe6e6e6e6, /* 0.9 * 256 */
5968 0x224488ff /* Nothing special */
5971 struct hugeVertex data2[4];
5972 IDirect3DVertexDeclaration9 *decl;
5973 HRESULT hr;
5974 unsigned int i;
5975 DWORD color, r, g, b, r_e, g_e, b_e;
5977 memcpy(data2, data, sizeof(data2));
5978 data2[0].pos_x = 0; data2[0].pos_y = 0;
5979 data2[1].pos_x = 640; data2[1].pos_y = 0;
5980 data2[2].pos_x = 0; data2[2].pos_y = 480;
5981 data2[3].pos_x = 640; data2[3].pos_y = 480;
5983 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5984 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5985 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5986 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5988 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5990 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5991 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5992 tests[i].name, hr);
5995 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5996 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5997 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6002 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6003 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6005 hr = IDirect3DDevice9_BeginScene(device);
6006 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6007 if(SUCCEEDED(hr))
6009 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6010 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6011 hr = IDirect3DDevice9_EndScene(device);
6012 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6015 color = getPixelColor(device, 360, 240);
6016 r = color & 0x00ff0000 >> 16;
6017 g = color & 0x0000ff00 >> 8;
6018 b = color & 0x000000ff;
6019 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6020 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
6021 b_e = tests[i].color_rhw & 0x000000ff;
6023 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6024 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6026 if(tests[i].todo_rhw) {
6027 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6028 * pipeline
6030 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6031 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6032 tests[i].name, color, tests[i].color_rhw);
6033 } else {
6034 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6035 "Test %s returned color 0x%08x, expected 0x%08x\n",
6036 tests[i].name, color, tests[i].color_rhw);
6040 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6042 IDirect3DPixelShader9_Release(tests[i].shader);
6045 IDirect3DVertexDeclaration9_Release(decl);
6048 static void test_compare_instructions(IDirect3DDevice9 *device)
6050 DWORD shader_sge_vec_code[] = {
6051 0xfffe0101, /* vs_1_1 */
6052 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6053 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6054 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6055 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6056 0x0000ffff /* end */
6058 DWORD shader_slt_vec_code[] = {
6059 0xfffe0101, /* vs_1_1 */
6060 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6061 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6062 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6063 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6064 0x0000ffff /* end */
6066 DWORD shader_sge_scalar_code[] = {
6067 0xfffe0101, /* vs_1_1 */
6068 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6069 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6070 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6071 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6072 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6073 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6074 0x0000ffff /* end */
6076 DWORD shader_slt_scalar_code[] = {
6077 0xfffe0101, /* vs_1_1 */
6078 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6079 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6080 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6081 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6082 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6083 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6084 0x0000ffff /* end */
6086 IDirect3DVertexShader9 *shader_sge_vec;
6087 IDirect3DVertexShader9 *shader_slt_vec;
6088 IDirect3DVertexShader9 *shader_sge_scalar;
6089 IDirect3DVertexShader9 *shader_slt_scalar;
6090 HRESULT hr, color;
6091 float quad1[] = {
6092 -1.0, -1.0, 0.1,
6093 0.0, -1.0, 0.1,
6094 -1.0, 0.0, 0.1,
6095 0.0, 0.0, 0.1
6097 float quad2[] = {
6098 0.0, -1.0, 0.1,
6099 1.0, -1.0, 0.1,
6100 0.0, 0.0, 0.1,
6101 1.0, 0.0, 0.1
6103 float quad3[] = {
6104 -1.0, 0.0, 0.1,
6105 0.0, 0.0, 0.1,
6106 -1.0, 1.0, 0.1,
6107 0.0, 1.0, 0.1
6109 float quad4[] = {
6110 0.0, 0.0, 0.1,
6111 1.0, 0.0, 0.1,
6112 0.0, 1.0, 0.1,
6113 1.0, 1.0, 0.1
6115 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6116 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6118 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6119 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6121 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6122 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6123 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6124 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6125 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6126 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6127 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6128 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6129 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6130 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6131 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6132 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6133 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6134 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6136 hr = IDirect3DDevice9_BeginScene(device);
6137 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6138 if(SUCCEEDED(hr))
6140 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6141 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6143 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6145 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6146 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6148 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6150 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6151 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6153 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6155 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6156 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6158 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6161 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6163 hr = IDirect3DDevice9_EndScene(device);
6164 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6167 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6168 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6170 color = getPixelColor(device, 160, 360);
6171 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6172 color = getPixelColor(device, 480, 360);
6173 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6174 color = getPixelColor(device, 160, 120);
6175 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6176 color = getPixelColor(device, 480, 160);
6177 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6179 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6182 IDirect3DVertexShader9_Release(shader_sge_vec);
6183 IDirect3DVertexShader9_Release(shader_slt_vec);
6184 IDirect3DVertexShader9_Release(shader_sge_scalar);
6185 IDirect3DVertexShader9_Release(shader_slt_scalar);
6188 static void test_vshader_input(IDirect3DDevice9 *device)
6190 static const DWORD swapped_shader_code_3[] =
6192 0xfffe0300, /* vs_3_0 */
6193 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6194 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6195 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6196 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6197 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6198 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6199 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6200 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6201 0x0000ffff /* end */
6203 static const DWORD swapped_shader_code_1[] =
6205 0xfffe0101, /* vs_1_1 */
6206 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6207 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6208 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6209 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6210 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6211 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6212 0x0000ffff /* end */
6214 static const DWORD swapped_shader_code_2[] =
6216 0xfffe0200, /* vs_2_0 */
6217 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6218 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6219 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6220 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6221 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6222 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6223 0x0000ffff /* end */
6225 static const DWORD texcoord_color_shader_code_3[] =
6227 0xfffe0300, /* vs_3_0 */
6228 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6229 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6230 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6231 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6232 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6233 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6234 0x0000ffff /* end */
6236 static const DWORD texcoord_color_shader_code_2[] =
6238 0xfffe0200, /* vs_2_0 */
6239 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6240 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6241 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6242 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6243 0x0000ffff /* end */
6245 static const DWORD texcoord_color_shader_code_1[] =
6247 0xfffe0101, /* vs_1_1 */
6248 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6249 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6250 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6251 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6252 0x0000ffff /* end */
6254 static const DWORD color_color_shader_code_3[] =
6256 0xfffe0300, /* vs_3_0 */
6257 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6258 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6259 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6260 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6261 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6262 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6263 0x0000ffff /* end */
6265 static const DWORD color_color_shader_code_2[] =
6267 0xfffe0200, /* vs_2_0 */
6268 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6269 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6270 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6271 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6272 0x0000ffff /* end */
6274 static const DWORD color_color_shader_code_1[] =
6276 0xfffe0101, /* vs_1_1 */
6277 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6278 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6279 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6280 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6281 0x0000ffff /* end */
6283 static const DWORD ps3_code[] =
6285 0xffff0300, /* ps_3_0 */
6286 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6287 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6288 0x0000ffff /* end */
6290 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6291 IDirect3DPixelShader9 *ps;
6292 HRESULT hr;
6293 DWORD color;
6294 float quad1[] = {
6295 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6296 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6297 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6298 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6300 float quad2[] = {
6301 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6302 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6303 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6304 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6306 float quad3[] = {
6307 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6308 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6309 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6310 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6312 float quad4[] = {
6313 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6314 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6315 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6316 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6318 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6319 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6320 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6321 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6322 D3DDECL_END()
6324 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6325 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6326 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6327 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6328 D3DDECL_END()
6330 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6331 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6332 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6333 D3DDECL_END()
6335 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6336 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6337 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6338 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6339 D3DDECL_END()
6341 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6342 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6343 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6344 D3DDECL_END()
6346 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6347 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6348 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6349 D3DDECL_END()
6351 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6352 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6353 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6354 D3DDECL_END()
6356 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6357 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6358 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6359 D3DDECL_END()
6361 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6362 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6363 unsigned int i;
6364 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6365 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6367 struct vertex quad1_color[] = {
6368 {-1.0, -1.0, 0.1, 0x00ff8040},
6369 { 0.0, -1.0, 0.1, 0x00ff8040},
6370 {-1.0, 0.0, 0.1, 0x00ff8040},
6371 { 0.0, 0.0, 0.1, 0x00ff8040}
6373 struct vertex quad2_color[] = {
6374 { 0.0, -1.0, 0.1, 0x00ff8040},
6375 { 1.0, -1.0, 0.1, 0x00ff8040},
6376 { 0.0, 0.0, 0.1, 0x00ff8040},
6377 { 1.0, 0.0, 0.1, 0x00ff8040}
6379 struct vertex quad3_color[] = {
6380 {-1.0, 0.0, 0.1, 0x00ff8040},
6381 { 0.0, 0.0, 0.1, 0x00ff8040},
6382 {-1.0, 1.0, 0.1, 0x00ff8040},
6383 { 0.0, 1.0, 0.1, 0x00ff8040}
6385 float quad4_color[] = {
6386 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6387 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6388 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6389 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6392 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6393 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6394 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6395 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6396 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6397 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6398 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6399 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6401 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6403 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6404 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6405 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6407 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6408 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6410 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6413 for(i = 1; i <= 3; i++) {
6414 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6415 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6416 if(i == 3) {
6417 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6419 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6420 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6421 } else if(i == 2){
6422 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6423 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6424 } else if(i == 1) {
6425 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6426 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6429 hr = IDirect3DDevice9_BeginScene(device);
6430 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6431 if(SUCCEEDED(hr))
6433 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6434 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6436 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6437 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6439 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6441 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6442 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6444 if(i == 3 || i == 2) {
6445 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6446 } else if(i == 1) {
6447 /* Succeeds or fails, depending on SW or HW vertex processing */
6448 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6451 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6452 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6454 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6456 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6457 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6459 if(i == 3 || i == 2) {
6460 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6461 } else if(i == 1) {
6462 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6465 hr = IDirect3DDevice9_EndScene(device);
6466 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6469 if(i == 3 || i == 2) {
6470 color = getPixelColor(device, 160, 360);
6471 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6472 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6474 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6475 color = getPixelColor(device, 480, 360);
6476 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6477 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6478 color = getPixelColor(device, 160, 120);
6479 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6480 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6481 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6483 color = getPixelColor(device, 480, 160);
6484 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6485 } else if(i == 1) {
6486 color = getPixelColor(device, 160, 360);
6487 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6488 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6489 color = getPixelColor(device, 480, 360);
6490 /* Accept the clear color as well in this case, since SW VP returns an error */
6491 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6492 color = getPixelColor(device, 160, 120);
6493 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6494 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6495 color = getPixelColor(device, 480, 160);
6496 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6499 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6500 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6502 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6503 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6505 /* Now find out if the whole streams are re-read, or just the last active value for the
6506 * vertices is used.
6508 hr = IDirect3DDevice9_BeginScene(device);
6509 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6510 if(SUCCEEDED(hr))
6512 float quad1_modified[] = {
6513 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6514 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6515 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6516 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6518 float quad2_modified[] = {
6519 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6520 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6521 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6522 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6525 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6526 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6528 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6529 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6531 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6533 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6534 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6536 if(i == 3 || i == 2) {
6537 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6538 } else if(i == 1) {
6539 /* Succeeds or fails, depending on SW or HW vertex processing */
6540 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6543 hr = IDirect3DDevice9_EndScene(device);
6544 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6547 color = getPixelColor(device, 480, 350);
6548 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6549 * as well.
6551 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6552 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6553 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6554 * refrast's result.
6556 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6558 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6559 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6561 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6562 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6564 IDirect3DDevice9_SetVertexShader(device, NULL);
6565 IDirect3DDevice9_SetPixelShader(device, NULL);
6566 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6568 IDirect3DVertexShader9_Release(swapped_shader);
6571 for(i = 1; i <= 3; i++) {
6572 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6573 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6574 if(i == 3) {
6575 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6576 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6577 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6578 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6579 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6580 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6581 } else if(i == 2){
6582 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6584 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6585 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6586 } else if(i == 1) {
6587 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6588 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6589 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6590 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6593 hr = IDirect3DDevice9_BeginScene(device);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6595 if(SUCCEEDED(hr))
6597 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6598 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6599 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6601 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6602 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6604 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6605 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6607 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6608 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6609 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6610 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6612 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6614 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6616 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6617 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6619 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6621 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6622 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6623 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6624 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6626 hr = IDirect3DDevice9_EndScene(device);
6627 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6629 IDirect3DDevice9_SetVertexShader(device, NULL);
6630 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6631 IDirect3DDevice9_SetPixelShader(device, NULL);
6633 color = getPixelColor(device, 160, 360);
6634 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6635 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6636 color = getPixelColor(device, 480, 360);
6637 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6638 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6639 color = getPixelColor(device, 160, 120);
6640 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6641 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6642 color = getPixelColor(device, 480, 160);
6643 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6644 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6646 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6647 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6649 IDirect3DVertexShader9_Release(texcoord_color_shader);
6650 IDirect3DVertexShader9_Release(color_color_shader);
6653 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6654 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6655 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6656 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6658 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6659 IDirect3DVertexDeclaration9_Release(decl_color_color);
6660 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6661 IDirect3DVertexDeclaration9_Release(decl_color_float);
6663 IDirect3DPixelShader9_Release(ps);
6666 static void srgbtexture_test(IDirect3DDevice9 *device)
6668 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6669 * texture stage state to render a quad using that texture. The resulting
6670 * color components should be 0x36 (~ 0.21), per this formula:
6671 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6672 * This is true where srgb_color > 0.04045.
6674 IDirect3D9 *d3d = NULL;
6675 HRESULT hr;
6676 LPDIRECT3DTEXTURE9 texture = NULL;
6677 LPDIRECT3DSURFACE9 surface = NULL;
6678 D3DLOCKED_RECT lr;
6679 DWORD color;
6680 float quad[] = {
6681 -1.0, 1.0, 0.0, 0.0, 0.0,
6682 1.0, 1.0, 0.0, 1.0, 0.0,
6683 -1.0, -1.0, 0.0, 0.0, 1.0,
6684 1.0, -1.0, 0.0, 1.0, 1.0,
6688 memset(&lr, 0, sizeof(lr));
6689 IDirect3DDevice9_GetDirect3D(device, &d3d);
6690 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6691 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6692 D3DFMT_A8R8G8B8) != D3D_OK) {
6693 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6694 goto out;
6697 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6698 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6699 &texture, NULL);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6701 if(!texture) {
6702 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6703 goto out;
6705 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6706 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6708 fill_surface(surface, 0xff7f7f7f);
6709 IDirect3DSurface9_Release(surface);
6711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6713 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6716 hr = IDirect3DDevice9_BeginScene(device);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6718 if(SUCCEEDED(hr))
6720 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6723 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6728 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6730 hr = IDirect3DDevice9_EndScene(device);
6731 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6734 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6735 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6736 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6737 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6739 color = getPixelColor(device, 320, 240);
6740 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6745 out:
6746 if(texture) IDirect3DTexture9_Release(texture);
6747 IDirect3D9_Release(d3d);
6750 static void shademode_test(IDirect3DDevice9 *device)
6752 /* Render a quad and try all of the different fixed function shading models. */
6753 HRESULT hr;
6754 DWORD color0, color1;
6755 DWORD color0_gouraud = 0, color1_gouraud = 0;
6756 DWORD shademode = D3DSHADE_FLAT;
6757 DWORD primtype = D3DPT_TRIANGLESTRIP;
6758 LPVOID data = NULL;
6759 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6760 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6761 UINT i, j;
6762 struct vertex quad_strip[] =
6764 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6765 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6766 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6767 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6769 struct vertex quad_list[] =
6771 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6772 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6773 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6775 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6776 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6777 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6780 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6781 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6782 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6783 if (FAILED(hr)) goto bail;
6785 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6786 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6787 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6788 if (FAILED(hr)) goto bail;
6790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6791 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6793 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6794 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6796 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6797 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6798 memcpy(data, quad_strip, sizeof(quad_strip));
6799 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6800 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6802 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6803 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6804 memcpy(data, quad_list, sizeof(quad_list));
6805 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6806 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6808 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6809 * the color fixups we have to do for FLAT shading will be dependent on that. */
6810 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6811 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6813 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6814 for (j=0; j<2; j++) {
6816 /* Inner loop just changes the D3DRS_SHADEMODE */
6817 for (i=0; i<3; i++) {
6818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6819 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6824 hr = IDirect3DDevice9_BeginScene(device);
6825 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6826 if(SUCCEEDED(hr))
6828 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6829 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6831 hr = IDirect3DDevice9_EndScene(device);
6832 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6835 /* Sample two spots from the output */
6836 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6837 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6838 switch(shademode) {
6839 case D3DSHADE_FLAT:
6840 /* Should take the color of the first vertex of each triangle */
6841 if (0)
6843 /* This test depends on EXT_provoking_vertex being
6844 * available. This extension is currently (20090810)
6845 * not common enough to let the test fail if it isn't
6846 * present. */
6847 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6848 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6850 shademode = D3DSHADE_GOURAUD;
6851 break;
6852 case D3DSHADE_GOURAUD:
6853 /* Should be an interpolated blend */
6855 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6856 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6857 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6858 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6860 color0_gouraud = color0;
6861 color1_gouraud = color1;
6863 shademode = D3DSHADE_PHONG;
6864 break;
6865 case D3DSHADE_PHONG:
6866 /* Should be the same as GOURAUD, since no hardware implements this */
6867 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6868 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6869 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6870 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6872 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6873 color0_gouraud, color0);
6874 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6875 color1_gouraud, color1);
6876 break;
6880 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6881 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6883 /* Now, do it all over again with a TRIANGLELIST */
6884 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6885 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6886 primtype = D3DPT_TRIANGLELIST;
6887 shademode = D3DSHADE_FLAT;
6890 bail:
6891 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6892 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6894 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6896 if (vb_strip)
6897 IDirect3DVertexBuffer9_Release(vb_strip);
6898 if (vb_list)
6899 IDirect3DVertexBuffer9_Release(vb_list);
6902 static void alpha_test(IDirect3DDevice9 *device)
6904 HRESULT hr;
6905 IDirect3DTexture9 *offscreenTexture;
6906 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6907 DWORD color;
6909 struct vertex quad1[] =
6911 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6912 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6913 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6914 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6916 struct vertex quad2[] =
6918 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6919 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6920 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6921 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6923 static const float composite_quad[][5] = {
6924 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6925 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6926 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6927 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6930 /* Clear the render target with alpha = 0.5 */
6931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6932 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6934 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6935 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6937 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6938 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6939 if(!backbuffer) {
6940 goto out;
6943 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6944 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6945 if(!offscreen) {
6946 goto out;
6949 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6950 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6952 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6953 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6954 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6955 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6956 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6957 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6958 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6959 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6961 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6964 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6965 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6967 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6971 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6973 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6978 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6980 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6982 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6983 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6984 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6985 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6986 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6987 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6988 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6991 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6993 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6995 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7000 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7002 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7004 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7005 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7007 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7008 * Disable alpha blending for the final composition
7010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7011 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7012 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7013 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7015 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7016 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7018 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7019 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7020 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7022 hr = IDirect3DDevice9_EndScene(device);
7023 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7026 color = getPixelColor(device, 160, 360);
7027 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7028 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7030 color = getPixelColor(device, 160, 120);
7031 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7032 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7034 color = getPixelColor(device, 480, 360);
7035 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7036 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7038 color = getPixelColor(device, 480, 120);
7039 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7040 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7042 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7044 out:
7045 /* restore things */
7046 if(backbuffer) {
7047 IDirect3DSurface9_Release(backbuffer);
7049 if(offscreenTexture) {
7050 IDirect3DTexture9_Release(offscreenTexture);
7052 if(offscreen) {
7053 IDirect3DSurface9_Release(offscreen);
7057 struct vertex_shortcolor {
7058 float x, y, z;
7059 unsigned short r, g, b, a;
7061 struct vertex_floatcolor {
7062 float x, y, z;
7063 float r, g, b, a;
7066 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7068 HRESULT hr;
7069 BOOL s_ok, ub_ok, f_ok;
7070 DWORD color, size, i;
7071 void *data;
7072 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7073 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7074 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7075 D3DDECL_END()
7077 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7078 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7079 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7080 D3DDECL_END()
7082 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7083 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7084 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7085 D3DDECL_END()
7087 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7088 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7089 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7090 D3DDECL_END()
7092 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7093 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7094 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7095 D3DDECL_END()
7097 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7098 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7099 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7100 D3DDECL_END()
7102 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7103 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7104 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7105 D3DDECL_END()
7107 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7108 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7109 IDirect3DVertexBuffer9 *vb, *vb2;
7110 struct vertex quad1[] = /* D3DCOLOR */
7112 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7113 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7114 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7115 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7117 struct vertex quad2[] = /* UBYTE4N */
7119 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7120 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7121 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7122 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7124 struct vertex_shortcolor quad3[] = /* short */
7126 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7127 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7128 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7129 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7131 struct vertex_floatcolor quad4[] =
7133 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7134 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7135 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7136 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7138 DWORD colors[] = {
7139 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7140 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7141 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7142 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7143 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7144 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7145 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
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,
7156 float quads[] = {
7157 -1.0, -1.0, 0.1,
7158 -1.0, 0.0, 0.1,
7159 0.0, -1.0, 0.1,
7160 0.0, 0.0, 0.1,
7162 0.0, -1.0, 0.1,
7163 0.0, 0.0, 0.1,
7164 1.0, -1.0, 0.1,
7165 1.0, 0.0, 0.1,
7167 0.0, 0.0, 0.1,
7168 0.0, 1.0, 0.1,
7169 1.0, 0.0, 0.1,
7170 1.0, 1.0, 0.1,
7172 -1.0, 0.0, 0.1,
7173 -1.0, 1.0, 0.1,
7174 0.0, 0.0, 0.1,
7175 0.0, 1.0, 0.1
7177 struct tvertex quad_transformed[] = {
7178 { 90, 110, 0.1, 2.0, 0x00ffff00},
7179 { 570, 110, 0.1, 2.0, 0x00ffff00},
7180 { 90, 300, 0.1, 2.0, 0x00ffff00},
7181 { 570, 300, 0.1, 2.0, 0x00ffff00}
7183 D3DCAPS9 caps;
7185 memset(&caps, 0, sizeof(caps));
7186 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7187 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7190 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7192 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7193 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7194 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7195 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7196 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7197 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7198 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7199 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7200 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7201 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7202 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7203 } else {
7204 trace("D3DDTCAPS_UBYTE4N not supported\n");
7205 dcl_ubyte_2 = NULL;
7206 dcl_ubyte = NULL;
7208 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7209 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7210 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7211 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7213 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7214 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7215 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7216 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7218 hr = IDirect3DDevice9_BeginScene(device);
7219 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7220 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7221 if(SUCCEEDED(hr)) {
7222 if(dcl_color) {
7223 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7224 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7226 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7229 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7230 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7231 * using software vertex processing. Doh!
7233 if(dcl_ubyte) {
7234 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7235 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7237 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7238 ub_ok = SUCCEEDED(hr);
7241 if(dcl_short) {
7242 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7243 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7245 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7246 s_ok = SUCCEEDED(hr);
7249 if(dcl_float) {
7250 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7251 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7252 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7253 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7254 f_ok = SUCCEEDED(hr);
7257 hr = IDirect3DDevice9_EndScene(device);
7258 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7261 if(dcl_short) {
7262 color = getPixelColor(device, 480, 360);
7263 ok(color == 0x000000ff || !s_ok,
7264 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7266 if(dcl_ubyte) {
7267 color = getPixelColor(device, 160, 120);
7268 ok(color == 0x0000ffff || !ub_ok,
7269 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7271 if(dcl_color) {
7272 color = getPixelColor(device, 160, 360);
7273 ok(color == 0x00ffff00,
7274 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7276 if(dcl_float) {
7277 color = getPixelColor(device, 480, 120);
7278 ok(color == 0x00ff0000 || !f_ok,
7279 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7281 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7283 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7284 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7285 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7286 * whether the immediate mode code works
7288 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7289 hr = IDirect3DDevice9_BeginScene(device);
7290 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7291 if(SUCCEEDED(hr)) {
7292 if(dcl_color) {
7293 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7294 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7295 memcpy(data, quad1, sizeof(quad1));
7296 hr = IDirect3DVertexBuffer9_Unlock(vb);
7297 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7298 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7299 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7300 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7301 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7302 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7303 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7306 if(dcl_ubyte) {
7307 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7308 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7309 memcpy(data, quad2, sizeof(quad2));
7310 hr = IDirect3DVertexBuffer9_Unlock(vb);
7311 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7312 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7313 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7314 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7315 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7316 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7317 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7318 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7319 ub_ok = SUCCEEDED(hr);
7322 if(dcl_short) {
7323 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7324 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7325 memcpy(data, quad3, sizeof(quad3));
7326 hr = IDirect3DVertexBuffer9_Unlock(vb);
7327 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7328 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7329 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7330 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7331 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7332 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7333 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7334 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7335 s_ok = SUCCEEDED(hr);
7338 if(dcl_float) {
7339 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7340 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7341 memcpy(data, quad4, sizeof(quad4));
7342 hr = IDirect3DVertexBuffer9_Unlock(vb);
7343 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7344 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7345 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7346 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7347 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7348 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7349 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7350 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7351 f_ok = SUCCEEDED(hr);
7354 hr = IDirect3DDevice9_EndScene(device);
7355 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7358 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7359 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7360 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7361 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7363 if(dcl_short) {
7364 color = getPixelColor(device, 480, 360);
7365 ok(color == 0x000000ff || !s_ok,
7366 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7368 if(dcl_ubyte) {
7369 color = getPixelColor(device, 160, 120);
7370 ok(color == 0x0000ffff || !ub_ok,
7371 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7373 if(dcl_color) {
7374 color = getPixelColor(device, 160, 360);
7375 ok(color == 0x00ffff00,
7376 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7378 if(dcl_float) {
7379 color = getPixelColor(device, 480, 120);
7380 ok(color == 0x00ff0000 || !f_ok,
7381 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7383 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7386 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7388 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7390 memcpy(data, quad_transformed, sizeof(quad_transformed));
7391 hr = IDirect3DVertexBuffer9_Unlock(vb);
7392 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7394 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7395 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7397 hr = IDirect3DDevice9_BeginScene(device);
7398 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7399 if(SUCCEEDED(hr)) {
7400 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7401 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7402 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7405 hr = IDirect3DDevice9_EndScene(device);
7406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7409 color = getPixelColor(device, 88, 108);
7410 ok(color == 0x000000ff,
7411 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7412 color = getPixelColor(device, 92, 108);
7413 ok(color == 0x000000ff,
7414 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7415 color = getPixelColor(device, 88, 112);
7416 ok(color == 0x000000ff,
7417 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7418 color = getPixelColor(device, 92, 112);
7419 ok(color == 0x00ffff00,
7420 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7422 color = getPixelColor(device, 568, 108);
7423 ok(color == 0x000000ff,
7424 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7425 color = getPixelColor(device, 572, 108);
7426 ok(color == 0x000000ff,
7427 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7428 color = getPixelColor(device, 568, 112);
7429 ok(color == 0x00ffff00,
7430 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7431 color = getPixelColor(device, 572, 112);
7432 ok(color == 0x000000ff,
7433 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7435 color = getPixelColor(device, 88, 298);
7436 ok(color == 0x000000ff,
7437 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7438 color = getPixelColor(device, 92, 298);
7439 ok(color == 0x00ffff00,
7440 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7441 color = getPixelColor(device, 88, 302);
7442 ok(color == 0x000000ff,
7443 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7444 color = getPixelColor(device, 92, 302);
7445 ok(color == 0x000000ff,
7446 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7448 color = getPixelColor(device, 568, 298);
7449 ok(color == 0x00ffff00,
7450 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7451 color = getPixelColor(device, 572, 298);
7452 ok(color == 0x000000ff,
7453 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7454 color = getPixelColor(device, 568, 302);
7455 ok(color == 0x000000ff,
7456 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7457 color = getPixelColor(device, 572, 302);
7458 ok(color == 0x000000ff,
7459 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7461 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7463 /* This test is pointless without those two declarations: */
7464 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7465 skip("color-ubyte switching test declarations aren't supported\n");
7466 goto out;
7469 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7470 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7471 memcpy(data, quads, sizeof(quads));
7472 hr = IDirect3DVertexBuffer9_Unlock(vb);
7473 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7474 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7475 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7476 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7477 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7478 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7479 memcpy(data, colors, sizeof(colors));
7480 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7481 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7483 for(i = 0; i < 2; i++) {
7484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7485 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7487 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7489 if(i == 0) {
7490 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7491 } else {
7492 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7494 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7496 hr = IDirect3DDevice9_BeginScene(device);
7497 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7498 ub_ok = FALSE;
7499 if(SUCCEEDED(hr)) {
7500 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7501 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7502 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7503 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7504 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7505 ub_ok = SUCCEEDED(hr);
7507 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7508 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7509 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7510 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7512 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7513 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7514 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7515 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7516 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7517 ub_ok = (SUCCEEDED(hr) && ub_ok);
7519 hr = IDirect3DDevice9_EndScene(device);
7520 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7523 if(i == 0) {
7524 color = getPixelColor(device, 480, 360);
7525 ok(color == 0x00ff0000,
7526 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7527 color = getPixelColor(device, 160, 120);
7528 ok(color == 0x00ffffff,
7529 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7530 color = getPixelColor(device, 160, 360);
7531 ok(color == 0x000000ff || !ub_ok,
7532 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7533 color = getPixelColor(device, 480, 120);
7534 ok(color == 0x000000ff || !ub_ok,
7535 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7536 } else {
7537 color = getPixelColor(device, 480, 360);
7538 ok(color == 0x000000ff,
7539 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7540 color = getPixelColor(device, 160, 120);
7541 ok(color == 0x00ffffff,
7542 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7543 color = getPixelColor(device, 160, 360);
7544 ok(color == 0x00ff0000 || !ub_ok,
7545 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7546 color = getPixelColor(device, 480, 120);
7547 ok(color == 0x00ff0000 || !ub_ok,
7548 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7550 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7553 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7554 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7555 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7556 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7557 IDirect3DVertexBuffer9_Release(vb2);
7559 out:
7560 IDirect3DVertexBuffer9_Release(vb);
7561 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7562 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7563 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7564 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7565 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7566 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7567 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7570 struct vertex_float16color {
7571 float x, y, z;
7572 DWORD c1, c2;
7575 static void test_vshader_float16(IDirect3DDevice9 *device)
7577 HRESULT hr;
7578 DWORD color;
7579 void *data;
7580 static const D3DVERTEXELEMENT9 decl_elements[] = {
7581 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7582 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7583 D3DDECL_END()
7585 IDirect3DVertexDeclaration9 *vdecl = NULL;
7586 IDirect3DVertexBuffer9 *buffer = NULL;
7587 IDirect3DVertexShader9 *shader;
7588 DWORD shader_code[] = {
7589 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7590 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7591 0x90e40001, 0x0000ffff
7593 struct vertex_float16color quad[] = {
7594 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7595 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7596 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7597 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7599 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7600 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7601 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7602 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7604 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7605 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7606 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7607 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7609 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7610 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7611 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7612 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7616 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7618 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7619 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7620 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7621 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7622 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7623 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7625 hr = IDirect3DDevice9_BeginScene(device);
7626 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7627 if(SUCCEEDED(hr)) {
7628 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7629 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7631 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7633 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7635 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7637 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7639 hr = IDirect3DDevice9_EndScene(device);
7640 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7642 color = getPixelColor(device, 480, 360);
7643 ok(color == 0x00ff0000,
7644 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7645 color = getPixelColor(device, 160, 120);
7646 ok(color == 0x00000000,
7647 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7648 color = getPixelColor(device, 160, 360);
7649 ok(color == 0x0000ff00,
7650 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7651 color = getPixelColor(device, 480, 120);
7652 ok(color == 0x000000ff,
7653 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7654 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7656 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7657 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7659 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7660 D3DPOOL_MANAGED, &buffer, NULL);
7661 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7662 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7663 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7664 memcpy(data, quad, sizeof(quad));
7665 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7666 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7667 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7668 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7670 hr = IDirect3DDevice9_BeginScene(device);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7672 if(SUCCEEDED(hr)) {
7673 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7675 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7676 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7677 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7679 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7680 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7682 hr = IDirect3DDevice9_EndScene(device);
7683 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7686 color = getPixelColor(device, 480, 360);
7687 ok(color == 0x00ff0000,
7688 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7689 color = getPixelColor(device, 160, 120);
7690 ok(color == 0x00000000,
7691 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7692 color = getPixelColor(device, 160, 360);
7693 ok(color == 0x0000ff00,
7694 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7695 color = getPixelColor(device, 480, 120);
7696 ok(color == 0x000000ff,
7697 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7698 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7700 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7701 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7702 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7703 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7704 IDirect3DDevice9_SetVertexShader(device, NULL);
7705 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7707 IDirect3DVertexDeclaration9_Release(vdecl);
7708 IDirect3DVertexShader9_Release(shader);
7709 IDirect3DVertexBuffer9_Release(buffer);
7712 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7714 D3DCAPS9 caps;
7715 IDirect3DTexture9 *texture;
7716 HRESULT hr;
7717 D3DLOCKED_RECT rect;
7718 unsigned int x, y;
7719 DWORD *dst, color;
7720 const float quad[] = {
7721 -1.0, -1.0, 0.1, -0.2, -0.2,
7722 1.0, -1.0, 0.1, 1.2, -0.2,
7723 -1.0, 1.0, 0.1, -0.2, 1.2,
7724 1.0, 1.0, 0.1, 1.2, 1.2
7726 memset(&caps, 0, sizeof(caps));
7728 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7729 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7730 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7731 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7732 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7733 "Card has conditional NP2 support without power of two restriction set\n");
7734 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7735 return;
7736 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7737 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7738 return;
7741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7744 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7745 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7747 memset(&rect, 0, sizeof(rect));
7748 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7749 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7750 for(y = 0; y < 10; y++) {
7751 for(x = 0; x < 10; x++) {
7752 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7753 if(x == 0 || x == 9 || y == 0 || y == 9) {
7754 *dst = 0x00ff0000;
7755 } else {
7756 *dst = 0x000000ff;
7760 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7761 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7763 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7764 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7765 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7766 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7767 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7768 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7769 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7770 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7772 hr = IDirect3DDevice9_BeginScene(device);
7773 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7774 if(SUCCEEDED(hr)) {
7775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7776 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7778 hr = IDirect3DDevice9_EndScene(device);
7779 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7782 color = getPixelColor(device, 1, 1);
7783 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7784 color = getPixelColor(device, 639, 479);
7785 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7787 color = getPixelColor(device, 135, 101);
7788 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7789 color = getPixelColor(device, 140, 101);
7790 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7791 color = getPixelColor(device, 135, 105);
7792 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7793 color = getPixelColor(device, 140, 105);
7794 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7796 color = getPixelColor(device, 135, 376);
7797 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7798 color = getPixelColor(device, 140, 376);
7799 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7800 color = getPixelColor(device, 135, 379);
7801 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7802 color = getPixelColor(device, 140, 379);
7803 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7805 color = getPixelColor(device, 500, 101);
7806 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7807 color = getPixelColor(device, 504, 101);
7808 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7809 color = getPixelColor(device, 500, 105);
7810 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7811 color = getPixelColor(device, 504, 105);
7812 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7814 color = getPixelColor(device, 500, 376);
7815 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7816 color = getPixelColor(device, 504, 376);
7817 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7818 color = getPixelColor(device, 500, 380);
7819 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7820 color = getPixelColor(device, 504, 380);
7821 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7823 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7825 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7826 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7827 IDirect3DTexture9_Release(texture);
7830 static void vFace_register_test(IDirect3DDevice9 *device)
7832 HRESULT hr;
7833 DWORD color;
7834 const DWORD shader_code[] = {
7835 0xffff0300, /* ps_3_0 */
7836 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7837 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7838 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7839 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7840 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7841 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7842 0x0000ffff /* END */
7844 const DWORD vshader_code[] = {
7845 0xfffe0300, /* vs_3_0 */
7846 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7847 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7848 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7849 0x0000ffff /* end */
7851 IDirect3DPixelShader9 *shader;
7852 IDirect3DVertexShader9 *vshader;
7853 IDirect3DTexture9 *texture;
7854 IDirect3DSurface9 *surface, *backbuffer;
7855 const float quad[] = {
7856 -1.0, -1.0, 0.1,
7857 1.0, -1.0, 0.1,
7858 -1.0, 0.0, 0.1,
7860 1.0, -1.0, 0.1,
7861 1.0, 0.0, 0.1,
7862 -1.0, 0.0, 0.1,
7864 -1.0, 0.0, 0.1,
7865 -1.0, 1.0, 0.1,
7866 1.0, 0.0, 0.1,
7868 1.0, 0.0, 0.1,
7869 -1.0, 1.0, 0.1,
7870 1.0, 1.0, 0.1,
7872 const float blit[] = {
7873 0.0, -1.0, 0.1, 0.0, 0.0,
7874 1.0, -1.0, 0.1, 1.0, 0.0,
7875 0.0, 1.0, 0.1, 0.0, 1.0,
7876 1.0, 1.0, 0.1, 1.0, 1.0,
7879 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7880 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7881 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7882 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7883 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7884 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7885 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7886 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7887 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7888 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7889 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7890 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7891 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7893 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7899 hr = IDirect3DDevice9_BeginScene(device);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7901 if(SUCCEEDED(hr)) {
7902 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7903 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7904 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7905 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7906 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7907 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7909 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7910 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7912 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7914 /* Blit the texture onto the back buffer to make it visible */
7915 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7916 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7917 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7918 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7919 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7920 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7922 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7925 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7926 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7929 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7931 hr = IDirect3DDevice9_EndScene(device);
7932 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7935 color = getPixelColor(device, 160, 360);
7936 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7937 color = getPixelColor(device, 160, 120);
7938 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7939 color = getPixelColor(device, 480, 360);
7940 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7941 color = getPixelColor(device, 480, 120);
7942 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7943 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7945 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7946 IDirect3DDevice9_SetTexture(device, 0, NULL);
7947 IDirect3DPixelShader9_Release(shader);
7948 IDirect3DVertexShader9_Release(vshader);
7949 IDirect3DSurface9_Release(surface);
7950 IDirect3DSurface9_Release(backbuffer);
7951 IDirect3DTexture9_Release(texture);
7954 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7956 HRESULT hr;
7957 DWORD color;
7958 int i;
7959 D3DCAPS9 caps;
7960 BOOL L6V5U5_supported = FALSE;
7961 IDirect3DTexture9 *tex1, *tex2;
7962 D3DLOCKED_RECT locked_rect;
7964 static const float quad[][7] = {
7965 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7966 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7967 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7968 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7971 static const D3DVERTEXELEMENT9 decl_elements[] = {
7972 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7973 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7974 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7975 D3DDECL_END()
7978 /* use asymmetric matrix to test loading */
7979 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7980 float scale, offset;
7982 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7983 IDirect3DTexture9 *texture = NULL;
7985 memset(&caps, 0, sizeof(caps));
7986 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7987 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7988 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7989 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7990 return;
7991 } else {
7992 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7993 * They report that it is not supported, but after that bump mapping works properly. So just test
7994 * if the format is generally supported, and check the BUMPENVMAP flag
7996 IDirect3D9 *d3d9;
7998 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7999 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8000 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8001 L6V5U5_supported = SUCCEEDED(hr);
8002 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8003 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8004 IDirect3D9_Release(d3d9);
8005 if(FAILED(hr)) {
8006 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8007 return;
8011 /* Generate the textures */
8012 generate_bumpmap_textures(device);
8014 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8015 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8016 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8017 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8018 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8019 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8020 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8021 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8024 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8026 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8027 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8028 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8030 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8031 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8032 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8033 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8034 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8035 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8037 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8038 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8040 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8041 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8043 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8044 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8047 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8048 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8049 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8050 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8052 hr = IDirect3DDevice9_BeginScene(device);
8053 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8056 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8058 hr = IDirect3DDevice9_EndScene(device);
8059 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8061 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8062 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8063 * But since testing the color match is not the purpose of the test don't be too picky
8065 color = getPixelColor(device, 320-32, 240);
8066 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8067 color = getPixelColor(device, 320+32, 240);
8068 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8069 color = getPixelColor(device, 320, 240-32);
8070 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8071 color = getPixelColor(device, 320, 240+32);
8072 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8073 color = getPixelColor(device, 320, 240);
8074 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8075 color = getPixelColor(device, 320+32, 240+32);
8076 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8077 color = getPixelColor(device, 320-32, 240+32);
8078 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8079 color = getPixelColor(device, 320+32, 240-32);
8080 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8081 color = getPixelColor(device, 320-32, 240-32);
8082 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8083 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8084 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8086 for(i = 0; i < 2; i++) {
8087 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8088 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8089 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8090 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8091 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8092 IDirect3DTexture9_Release(texture); /* To destroy it */
8095 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8096 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8097 goto cleanup;
8099 if(L6V5U5_supported == FALSE) {
8100 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8101 goto cleanup;
8104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8106 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8107 * would only make this test more complicated
8109 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8110 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8111 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8112 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8114 memset(&locked_rect, 0, sizeof(locked_rect));
8115 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8116 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8117 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8118 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8119 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8121 memset(&locked_rect, 0, sizeof(locked_rect));
8122 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8123 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8124 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8125 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8126 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8128 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8129 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8130 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8131 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8133 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8134 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8135 scale = 2.0;
8136 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8137 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8138 offset = 0.1;
8139 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8140 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8142 hr = IDirect3DDevice9_BeginScene(device);
8143 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8144 if(SUCCEEDED(hr)) {
8145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8146 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8147 hr = IDirect3DDevice9_EndScene(device);
8148 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8151 color = getPixelColor(device, 320, 240);
8152 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8153 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8154 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8156 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8157 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8158 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8160 /* Check a result scale factor > 1.0 */
8161 scale = 10;
8162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8163 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8164 offset = 10;
8165 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8166 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8168 hr = IDirect3DDevice9_BeginScene(device);
8169 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8170 if(SUCCEEDED(hr)) {
8171 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8172 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8173 hr = IDirect3DDevice9_EndScene(device);
8174 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8176 color = getPixelColor(device, 320, 240);
8177 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8178 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8179 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8181 /* Check clamping in the scale factor calculation */
8182 scale = 1000;
8183 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8184 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8185 offset = -1;
8186 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8187 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8189 hr = IDirect3DDevice9_BeginScene(device);
8190 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8191 if(SUCCEEDED(hr)) {
8192 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8193 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8194 hr = IDirect3DDevice9_EndScene(device);
8195 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8197 color = getPixelColor(device, 320, 240);
8198 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8199 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8200 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8202 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8203 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8204 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8205 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8207 IDirect3DTexture9_Release(tex1);
8208 IDirect3DTexture9_Release(tex2);
8210 cleanup:
8211 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8212 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8213 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8214 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8216 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8217 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8218 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8221 static void stencil_cull_test(IDirect3DDevice9 *device) {
8222 HRESULT hr;
8223 IDirect3DSurface9 *depthstencil = NULL;
8224 D3DSURFACE_DESC desc;
8225 float quad1[] = {
8226 -1.0, -1.0, 0.1,
8227 0.0, -1.0, 0.1,
8228 -1.0, 0.0, 0.1,
8229 0.0, 0.0, 0.1,
8231 float quad2[] = {
8232 0.0, -1.0, 0.1,
8233 1.0, -1.0, 0.1,
8234 0.0, 0.0, 0.1,
8235 1.0, 0.0, 0.1,
8237 float quad3[] = {
8238 0.0, 0.0, 0.1,
8239 1.0, 0.0, 0.1,
8240 0.0, 1.0, 0.1,
8241 1.0, 1.0, 0.1,
8243 float quad4[] = {
8244 -1.0, 0.0, 0.1,
8245 0.0, 0.0, 0.1,
8246 -1.0, 1.0, 0.1,
8247 0.0, 1.0, 0.1,
8249 struct vertex painter[] = {
8250 {-1.0, -1.0, 0.0, 0x00000000},
8251 { 1.0, -1.0, 0.0, 0x00000000},
8252 {-1.0, 1.0, 0.0, 0x00000000},
8253 { 1.0, 1.0, 0.0, 0x00000000},
8255 WORD indices_cw[] = {0, 1, 3};
8256 WORD indices_ccw[] = {0, 2, 3};
8257 unsigned int i;
8258 DWORD color;
8260 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8261 if(depthstencil == NULL) {
8262 skip("No depth stencil buffer\n");
8263 return;
8265 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8266 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8267 IDirect3DSurface9_Release(depthstencil);
8268 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8269 skip("No 4 or 8 bit stencil surface\n");
8270 return;
8273 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8275 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8278 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8280 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8282 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8296 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8298 /* First pass: Fill the stencil buffer with some values... */
8299 hr = IDirect3DDevice9_BeginScene(device);
8300 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8301 if(SUCCEEDED(hr))
8303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8305 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8306 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8307 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8308 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8309 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8310 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8317 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8318 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8319 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8320 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8321 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8324 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8325 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8326 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8327 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8328 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8329 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8330 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8334 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8335 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8336 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8337 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8338 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8339 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8341 hr = IDirect3DDevice9_EndScene(device);
8342 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8345 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8347 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8349 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8353 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8355 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8357 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8359 /* 2nd pass: Make the stencil values visible */
8360 hr = IDirect3DDevice9_BeginScene(device);
8361 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8362 if(SUCCEEDED(hr))
8364 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8365 for(i = 0; i < 16; i++) {
8366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8369 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8370 painter[1].diffuse = (i * 16);
8371 painter[2].diffuse = (i * 16);
8372 painter[3].diffuse = (i * 16);
8373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8374 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8376 hr = IDirect3DDevice9_EndScene(device);
8377 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8381 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8383 color = getPixelColor(device, 160, 420);
8384 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8385 color = getPixelColor(device, 160, 300);
8386 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8388 color = getPixelColor(device, 480, 420);
8389 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8390 color = getPixelColor(device, 480, 300);
8391 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8393 color = getPixelColor(device, 160, 180);
8394 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8395 color = getPixelColor(device, 160, 60);
8396 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8398 color = getPixelColor(device, 480, 180);
8399 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8400 color = getPixelColor(device, 480, 60);
8401 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8403 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8404 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8407 static void vpos_register_test(IDirect3DDevice9 *device)
8409 HRESULT hr;
8410 DWORD color;
8411 const DWORD shader_code[] = {
8412 0xffff0300, /* ps_3_0 */
8413 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8414 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8415 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8416 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8417 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8418 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8419 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8420 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8421 0x0000ffff /* end */
8423 const DWORD shader_frac_code[] = {
8424 0xffff0300, /* ps_3_0 */
8425 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8426 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8427 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8428 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8429 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8430 0x0000ffff /* end */
8432 const DWORD vshader_code[] = {
8433 0xfffe0300, /* vs_3_0 */
8434 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8435 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8436 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8437 0x0000ffff /* end */
8439 IDirect3DVertexShader9 *vshader;
8440 IDirect3DPixelShader9 *shader, *shader_frac;
8441 IDirect3DSurface9 *surface = NULL, *backbuffer;
8442 const float quad[] = {
8443 -1.0, -1.0, 0.1, 0.0, 0.0,
8444 1.0, -1.0, 0.1, 1.0, 0.0,
8445 -1.0, 1.0, 0.1, 0.0, 1.0,
8446 1.0, 1.0, 0.1, 1.0, 1.0,
8448 D3DLOCKED_RECT lr;
8449 float constant[4] = {1.0, 0.0, 320, 240};
8450 DWORD *pos;
8452 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8453 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8454 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8455 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8456 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8457 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8458 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8459 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8460 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8461 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8462 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8464 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8465 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8466 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8469 hr = IDirect3DDevice9_BeginScene(device);
8470 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8471 if(SUCCEEDED(hr)) {
8472 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8473 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8475 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8476 hr = IDirect3DDevice9_EndScene(device);
8477 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8480 /* This has to be pixel exact */
8481 color = getPixelColor(device, 319, 239);
8482 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8483 color = getPixelColor(device, 320, 239);
8484 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8485 color = getPixelColor(device, 319, 240);
8486 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8487 color = getPixelColor(device, 320, 240);
8488 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8489 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8491 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8492 &surface, NULL);
8493 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8494 hr = IDirect3DDevice9_BeginScene(device);
8495 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8496 if(SUCCEEDED(hr)) {
8497 constant[2] = 16; constant[3] = 16;
8498 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8499 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8501 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8502 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8503 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8504 hr = IDirect3DDevice9_EndScene(device);
8505 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8507 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8508 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8510 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8511 color = *pos & 0x00ffffff;
8512 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8513 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8514 color = *pos & 0x00ffffff;
8515 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8516 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8517 color = *pos & 0x00ffffff;
8518 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8519 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8520 color = *pos & 0x00ffffff;
8521 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8523 hr = IDirect3DSurface9_UnlockRect(surface);
8524 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8526 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8527 * have full control over the multisampling setting inside this test
8529 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8530 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8531 hr = IDirect3DDevice9_BeginScene(device);
8532 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8533 if(SUCCEEDED(hr)) {
8534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8535 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8537 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8538 hr = IDirect3DDevice9_EndScene(device);
8539 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8541 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8542 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8544 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8545 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8547 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8548 color = *pos & 0x00ffffff;
8549 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8551 hr = IDirect3DSurface9_UnlockRect(surface);
8552 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8554 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8555 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8556 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8557 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8558 IDirect3DPixelShader9_Release(shader);
8559 IDirect3DPixelShader9_Release(shader_frac);
8560 IDirect3DVertexShader9_Release(vshader);
8561 if(surface) IDirect3DSurface9_Release(surface);
8562 IDirect3DSurface9_Release(backbuffer);
8565 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8567 D3DCOLOR color;
8569 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8570 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8571 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8572 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8573 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8575 ++r;
8576 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 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 return TRUE;
8585 static void pointsize_test(IDirect3DDevice9 *device)
8587 HRESULT hr;
8588 D3DCAPS9 caps;
8589 D3DMATRIX matrix;
8590 D3DMATRIX identity;
8591 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8592 DWORD color;
8593 IDirect3DSurface9 *rt, *backbuffer;
8594 IDirect3DTexture9 *tex1, *tex2;
8595 RECT rect = {0, 0, 128, 128};
8596 D3DLOCKED_RECT lr;
8597 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8598 0x00000000, 0x00000000};
8599 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8600 0x00000000, 0x0000ff00};
8602 const float vertices[] = {
8603 64, 64, 0.1,
8604 128, 64, 0.1,
8605 192, 64, 0.1,
8606 256, 64, 0.1,
8607 320, 64, 0.1,
8608 384, 64, 0.1,
8609 448, 64, 0.1,
8610 512, 64, 0.1,
8613 /* 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 */
8614 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;
8615 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;
8616 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;
8617 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;
8619 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;
8620 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;
8621 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;
8622 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;
8624 memset(&caps, 0, sizeof(caps));
8625 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8626 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8627 if(caps.MaxPointSize < 32.0) {
8628 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8629 return;
8632 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8633 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8634 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8635 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8636 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8637 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8638 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8639 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8641 hr = IDirect3DDevice9_BeginScene(device);
8642 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8643 if (SUCCEEDED(hr))
8645 ptsize = 15.0;
8646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8649 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8651 ptsize = 31.0;
8652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8653 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8655 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8657 ptsize = 30.75;
8658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8659 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8660 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8661 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8663 if (caps.MaxPointSize >= 63.0)
8665 ptsize = 63.0;
8666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8668 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8669 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8671 ptsize = 62.75;
8672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8673 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8675 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8678 ptsize = 1.0;
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[12], sizeof(float) * 3);
8682 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8684 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8685 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8686 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8687 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8689 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8690 ptsize = 15.0;
8691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8692 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8693 ptsize = 1.0;
8694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8695 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8697 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8700 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8702 /* pointsize < pointsize_min < pointsize_max?
8703 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8704 ptsize = 1.0;
8705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8706 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8707 ptsize = 15.0;
8708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8709 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8710 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8711 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8716 hr = IDirect3DDevice9_EndScene(device);
8717 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8720 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8721 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8722 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8724 if (caps.MaxPointSize >= 63.0)
8726 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8727 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8730 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8731 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8732 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8733 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8734 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8736 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8738 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8739 * generates texture coordinates for the point(result: Yes, it does)
8741 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8742 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8743 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8748 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8749 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8750 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8751 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8752 memset(&lr, 0, sizeof(lr));
8753 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8754 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8755 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8756 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8757 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8758 memset(&lr, 0, sizeof(lr));
8759 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8760 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8761 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8762 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8763 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8764 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8765 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8766 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8767 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8770 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8771 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8772 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8773 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8774 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8775 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8776 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8777 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8781 ptsize = 32.0;
8782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8783 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8785 hr = IDirect3DDevice9_BeginScene(device);
8786 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8787 if(SUCCEEDED(hr))
8789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8790 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8791 hr = IDirect3DDevice9_EndScene(device);
8792 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8795 color = getPixelColor(device, 64-4, 64-4);
8796 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8797 color = getPixelColor(device, 64-4, 64+4);
8798 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8799 color = getPixelColor(device, 64+4, 64+4);
8800 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8801 color = getPixelColor(device, 64+4, 64-4);
8802 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8803 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8805 U(matrix).m[0][0] = 1.0f / 64.0f;
8806 U(matrix).m[1][1] = -1.0f / 64.0f;
8807 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8808 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8810 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8811 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8813 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8814 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8815 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8817 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8818 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8819 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8820 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8822 hr = IDirect3DDevice9_BeginScene(device);
8823 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8824 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8825 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8826 hr = IDirect3DDevice9_EndScene(device);
8827 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8829 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8830 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8831 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8832 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8833 IDirect3DSurface9_Release(backbuffer);
8834 IDirect3DSurface9_Release(rt);
8836 color = getPixelColor(device, 64-4, 64-4);
8837 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8838 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8839 color = getPixelColor(device, 64+4, 64-4);
8840 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8841 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8842 color = getPixelColor(device, 64-4, 64+4);
8843 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8844 "Expected color 0x00000000, got 0x%08x.\n", color);
8845 color = getPixelColor(device, 64+4, 64+4);
8846 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8847 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8849 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8850 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8852 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8853 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8854 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8855 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8856 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8857 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8858 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8859 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8860 IDirect3DTexture9_Release(tex1);
8861 IDirect3DTexture9_Release(tex2);
8863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8864 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8866 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8867 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8868 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8871 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8873 static const DWORD vshader_code[] =
8875 0xfffe0300, /* vs_3_0 */
8876 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8877 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8878 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8879 0x0000ffff /* end */
8881 static const DWORD pshader_code1[] =
8883 0xffff0300, /* ps_3_0 */
8884 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8885 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8886 0x0000ffff /* end */
8888 static const DWORD pshader_code2[] =
8890 0xffff0300, /* ps_3_0 */
8891 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8892 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8893 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8894 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8895 0x0000ffff /* end */
8898 HRESULT hr;
8899 IDirect3DVertexShader9 *vs;
8900 IDirect3DPixelShader9 *ps1, *ps2;
8901 IDirect3DTexture9 *tex1, *tex2;
8902 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8903 D3DCAPS9 caps;
8904 DWORD color;
8905 UINT i, j;
8906 float quad[] = {
8907 -1.0, -1.0, 0.1,
8908 1.0, -1.0, 0.1,
8909 -1.0, 1.0, 0.1,
8910 1.0, 1.0, 0.1,
8912 float texquad[] = {
8913 -1.0, -1.0, 0.1, 0.0, 0.0,
8914 0.0, -1.0, 0.1, 1.0, 0.0,
8915 -1.0, 1.0, 0.1, 0.0, 1.0,
8916 0.0, 1.0, 0.1, 1.0, 1.0,
8918 0.0, -1.0, 0.1, 0.0, 0.0,
8919 1.0, -1.0, 0.1, 1.0, 0.0,
8920 0.0, 1.0, 0.1, 0.0, 1.0,
8921 1.0, 1.0, 0.1, 1.0, 1.0,
8924 memset(&caps, 0, sizeof(caps));
8925 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8926 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8927 if(caps.NumSimultaneousRTs < 2) {
8928 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8929 return;
8932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8933 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8935 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8936 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8937 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8939 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8940 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8941 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8942 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8943 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8944 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8945 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8946 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8947 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8948 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8949 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8950 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8952 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8953 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8954 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8955 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8956 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8957 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8959 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8960 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8961 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8962 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8963 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8964 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8965 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8966 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8969 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8970 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8971 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8972 color = getPixelColorFromSurface(readback, 8, 8);
8973 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8974 "Expected color 0x000000ff, got 0x%08x.\n", color);
8975 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8976 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8977 color = getPixelColorFromSurface(readback, 8, 8);
8978 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8979 "Expected color 0x000000ff, got 0x%08x.\n", color);
8981 /* Render targets not written by the pixel shader should be unmodified. */
8982 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8983 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8984 hr = IDirect3DDevice9_BeginScene(device);
8985 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8987 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8988 hr = IDirect3DDevice9_EndScene(device);
8989 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8990 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8991 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8992 color = getPixelColorFromSurface(readback, 8, 8);
8993 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8994 "Expected color 0xff00ff00, got 0x%08x.\n", color);
8995 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8996 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8997 for (i = 6; i < 10; ++i)
8999 for (j = 6; j < 10; ++j)
9001 color = getPixelColorFromSurface(readback, j, i);
9002 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9003 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9007 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9008 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9009 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9010 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9011 color = getPixelColorFromSurface(readback, 8, 8);
9012 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9013 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9014 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9015 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9016 color = getPixelColorFromSurface(readback, 8, 8);
9017 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9018 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9020 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9021 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9023 hr = IDirect3DDevice9_BeginScene(device);
9024 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9025 if(SUCCEEDED(hr)) {
9026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9027 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9029 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9030 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9031 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9033 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9034 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9035 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9036 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9037 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9038 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9040 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9041 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9043 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9045 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9048 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9050 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9051 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9053 hr = IDirect3DDevice9_EndScene(device);
9054 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9057 color = getPixelColor(device, 160, 240);
9058 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9059 color = getPixelColor(device, 480, 240);
9060 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9061 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9063 IDirect3DPixelShader9_Release(ps2);
9064 IDirect3DPixelShader9_Release(ps1);
9065 IDirect3DVertexShader9_Release(vs);
9066 IDirect3DTexture9_Release(tex1);
9067 IDirect3DTexture9_Release(tex2);
9068 IDirect3DSurface9_Release(surf1);
9069 IDirect3DSurface9_Release(surf2);
9070 IDirect3DSurface9_Release(backbuf);
9071 IDirect3DSurface9_Release(readback);
9074 struct formats {
9075 const char *fmtName;
9076 D3DFORMAT textureFormat;
9077 DWORD resultColorBlending;
9078 DWORD resultColorNoBlending;
9081 static const struct formats test_formats[] = {
9082 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9083 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9084 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9085 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9086 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9087 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9088 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9089 { NULL, 0 }
9092 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9094 HRESULT hr;
9095 IDirect3DTexture9 *offscreenTexture = NULL;
9096 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9097 IDirect3D9 *d3d = NULL;
9098 DWORD color;
9099 DWORD r0, g0, b0, r1, g1, b1;
9100 int fmt_index;
9102 static const float quad[][5] = {
9103 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9104 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9105 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9106 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9109 /* Quad with R=0x10, G=0x20 */
9110 static const struct vertex quad1[] = {
9111 {-1.0f, -1.0f, 0.1f, 0x80102000},
9112 {-1.0f, 1.0f, 0.1f, 0x80102000},
9113 { 1.0f, -1.0f, 0.1f, 0x80102000},
9114 { 1.0f, 1.0f, 0.1f, 0x80102000},
9117 /* Quad with R=0x20, G=0x10 */
9118 static const struct vertex quad2[] = {
9119 {-1.0f, -1.0f, 0.1f, 0x80201000},
9120 {-1.0f, 1.0f, 0.1f, 0x80201000},
9121 { 1.0f, -1.0f, 0.1f, 0x80201000},
9122 { 1.0f, 1.0f, 0.1f, 0x80201000},
9125 IDirect3DDevice9_GetDirect3D(device, &d3d);
9127 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9128 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9129 if(!backbuffer) {
9130 goto out;
9133 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9135 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9137 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9138 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9140 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9141 continue;
9144 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9145 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9147 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9148 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9149 if(!offscreenTexture) {
9150 continue;
9153 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9154 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9155 if(!offscreen) {
9156 continue;
9159 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9160 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9163 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9164 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9165 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9166 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9167 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9168 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9169 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9171 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9173 /* Below we will draw two quads with different colors and try to blend them together.
9174 * The result color is compared with the expected outcome.
9176 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9177 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9178 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9179 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9180 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9183 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9185 /* Draw a quad using color 0x0010200 */
9186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9187 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9189 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9191 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9193 /* Draw a quad using color 0x0020100 */
9194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9195 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9197 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9199 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9201 /* We don't want to blend the result on the backbuffer */
9202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9203 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9205 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9206 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9207 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9208 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9209 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9211 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9212 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9214 /* This time with the texture */
9215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9216 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9218 IDirect3DDevice9_EndScene(device);
9221 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9222 /* Compare the color of the center quad with our expectation */
9223 color = getPixelColor(device, 320, 240);
9224 r0 = (color & 0x00ff0000) >> 16;
9225 g0 = (color & 0x0000ff00) >> 8;
9226 b0 = (color & 0x000000ff) >> 0;
9228 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9229 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9230 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9232 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9233 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9234 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9235 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9236 } else {
9237 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9238 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9239 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9240 color = getPixelColor(device, 320, 240);
9241 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);
9243 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9245 IDirect3DDevice9_SetTexture(device, 0, NULL);
9246 if(offscreenTexture) {
9247 IDirect3DTexture9_Release(offscreenTexture);
9249 if(offscreen) {
9250 IDirect3DSurface9_Release(offscreen);
9254 out:
9255 /* restore things */
9256 if(backbuffer) {
9257 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9258 IDirect3DSurface9_Release(backbuffer);
9262 static void tssargtemp_test(IDirect3DDevice9 *device)
9264 HRESULT hr;
9265 DWORD color;
9266 static const struct vertex quad[] = {
9267 {-1.0, -1.0, 0.1, 0x00ff0000},
9268 { 1.0, -1.0, 0.1, 0x00ff0000},
9269 {-1.0, 1.0, 0.1, 0x00ff0000},
9270 { 1.0, 1.0, 0.1, 0x00ff0000}
9272 D3DCAPS9 caps;
9274 memset(&caps, 0, sizeof(caps));
9275 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9276 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9277 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9278 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9279 return;
9282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9283 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9285 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9286 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9288 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9290 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9291 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9292 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9293 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9294 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9295 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9297 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9298 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9299 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9300 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9301 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9302 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9304 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9305 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9308 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9309 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9310 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9312 hr = IDirect3DDevice9_BeginScene(device);
9313 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9314 if(SUCCEEDED(hr)) {
9315 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9316 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9317 hr = IDirect3DDevice9_EndScene(device);
9318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9320 color = getPixelColor(device, 320, 240);
9321 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9322 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9324 /* Set stage 1 back to default */
9325 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9326 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9327 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9328 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9329 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9330 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9331 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9332 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9333 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9334 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9337 struct testdata
9339 DWORD idxVertex; /* number of instances in the first stream */
9340 DWORD idxColor; /* number of instances in the second stream */
9341 DWORD idxInstance; /* should be 1 ?? */
9342 DWORD color1; /* color 1 instance */
9343 DWORD color2; /* color 2 instance */
9344 DWORD color3; /* color 3 instance */
9345 DWORD color4; /* color 4 instance */
9346 WORD strVertex; /* specify which stream to use 0-2*/
9347 WORD strColor;
9348 WORD strInstance;
9351 static const struct testdata testcases[]=
9353 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9354 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9355 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9356 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9357 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9358 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9359 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9360 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9361 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9362 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9363 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9364 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9365 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9366 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9368 This draws one instance on some machines, no instance on others
9369 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9372 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9373 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9377 /* Drawing Indexed Geometry with instances*/
9378 static void stream_test(IDirect3DDevice9 *device)
9380 IDirect3DVertexBuffer9 *vb = NULL;
9381 IDirect3DVertexBuffer9 *vb2 = NULL;
9382 IDirect3DVertexBuffer9 *vb3 = NULL;
9383 IDirect3DIndexBuffer9 *ib = NULL;
9384 IDirect3DVertexDeclaration9 *pDecl = NULL;
9385 IDirect3DVertexShader9 *shader = NULL;
9386 HRESULT hr;
9387 BYTE *data;
9388 DWORD color;
9389 DWORD ind;
9390 unsigned i;
9392 const DWORD shader_code[] =
9394 0xfffe0101, /* vs_1_1 */
9395 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9396 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9397 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9398 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9399 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9400 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9401 0x0000ffff
9404 const float quad[][3] =
9406 {-0.5f, -0.5f, 1.1f}, /*0 */
9407 {-0.5f, 0.5f, 1.1f}, /*1 */
9408 { 0.5f, -0.5f, 1.1f}, /*2 */
9409 { 0.5f, 0.5f, 1.1f}, /*3 */
9412 const float vertcolor[][4] =
9414 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9415 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9416 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9417 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9420 /* 4 position for 4 instances */
9421 const float instancepos[][3] =
9423 {-0.6f,-0.6f, 0.0f},
9424 { 0.6f,-0.6f, 0.0f},
9425 { 0.6f, 0.6f, 0.0f},
9426 {-0.6f, 0.6f, 0.0f},
9429 short indices[] = {0, 1, 2, 1, 2, 3};
9431 D3DVERTEXELEMENT9 decl[] =
9433 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9434 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9435 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9436 D3DDECL_END()
9439 /* set the default value because it isn't done in wine? */
9440 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9441 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9443 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9444 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9445 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9447 /* check wrong cases */
9448 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9449 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9450 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9451 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9452 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9453 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9454 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9455 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9456 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9457 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9458 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9459 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9460 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9461 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9462 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9463 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9464 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9465 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9466 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9467 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9469 /* set the default value back */
9470 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9471 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9473 /* create all VertexBuffers*/
9474 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9475 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9476 if(!vb) {
9477 skip("Failed to create a vertex buffer\n");
9478 return;
9480 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9481 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9482 if(!vb2) {
9483 skip("Failed to create a vertex buffer\n");
9484 goto out;
9486 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9487 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9488 if(!vb3) {
9489 skip("Failed to create a vertex buffer\n");
9490 goto out;
9493 /* create IndexBuffer*/
9494 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9495 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9496 if(!ib) {
9497 skip("Failed to create a index buffer\n");
9498 goto out;
9501 /* copy all Buffers (Vertex + Index)*/
9502 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9503 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9504 memcpy(data, quad, sizeof(quad));
9505 hr = IDirect3DVertexBuffer9_Unlock(vb);
9506 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9507 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9508 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9509 memcpy(data, vertcolor, sizeof(vertcolor));
9510 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9511 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9512 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9513 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9514 memcpy(data, instancepos, sizeof(instancepos));
9515 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9516 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9517 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9518 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9519 memcpy(data, indices, sizeof(indices));
9520 hr = IDirect3DIndexBuffer9_Unlock(ib);
9521 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9523 /* create VertexShader */
9524 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9525 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9526 if(!shader) {
9527 skip("Failed to create a vetex shader\n");
9528 goto out;
9531 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9532 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9534 hr = IDirect3DDevice9_SetIndices(device, ib);
9535 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9537 /* run all tests */
9538 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9540 struct testdata act = testcases[i];
9541 decl[0].Stream = act.strVertex;
9542 decl[1].Stream = act.strColor;
9543 decl[2].Stream = act.strInstance;
9544 /* create VertexDeclarations */
9545 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9546 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9549 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9551 hr = IDirect3DDevice9_BeginScene(device);
9552 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9553 if(SUCCEEDED(hr))
9555 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9556 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9558 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9559 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9560 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9561 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9563 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9564 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9565 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9566 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9568 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9569 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9570 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9571 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9573 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9574 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9575 hr = IDirect3DDevice9_EndScene(device);
9576 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9578 /* set all StreamSource && StreamSourceFreq back to default */
9579 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9580 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9581 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9582 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9583 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9584 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9585 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9586 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9587 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9588 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9589 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9590 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9593 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9594 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9596 color = getPixelColor(device, 160, 360);
9597 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9598 color = getPixelColor(device, 480, 360);
9599 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9600 color = getPixelColor(device, 480, 120);
9601 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9602 color = getPixelColor(device, 160, 120);
9603 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9605 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9606 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9609 hr = IDirect3DDevice9_SetIndices(device, NULL);
9610 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9612 out:
9613 if(vb) IDirect3DVertexBuffer9_Release(vb);
9614 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9615 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9616 if(ib)IDirect3DIndexBuffer9_Release(ib);
9617 if(shader)IDirect3DVertexShader9_Release(shader);
9620 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9621 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9622 IDirect3DTexture9 *dsttex = NULL;
9623 HRESULT hr;
9624 DWORD color;
9625 D3DRECT r1 = {0, 0, 50, 50 };
9626 D3DRECT r2 = {50, 0, 100, 50 };
9627 D3DRECT r3 = {50, 50, 100, 100};
9628 D3DRECT r4 = {0, 50, 50, 100};
9629 const float quad[] = {
9630 -1.0, -1.0, 0.1, 0.0, 0.0,
9631 1.0, -1.0, 0.1, 1.0, 0.0,
9632 -1.0, 1.0, 0.1, 0.0, 1.0,
9633 1.0, 1.0, 0.1, 1.0, 1.0,
9636 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9637 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9639 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9640 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9641 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9642 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9644 if(!src || !dsttex) {
9645 skip("One or more test resources could not be created\n");
9646 goto cleanup;
9649 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9650 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9652 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9653 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9655 /* Clear the StretchRect destination for debugging */
9656 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9657 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9659 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9661 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9662 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9664 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9665 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9666 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9667 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9668 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9670 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9671 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9673 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9674 * the target -> texture GL blit path
9676 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9677 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9678 IDirect3DSurface9_Release(dst);
9680 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9683 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9684 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9685 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9686 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9687 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9688 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9689 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9690 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9692 hr = IDirect3DDevice9_BeginScene(device);
9693 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9694 if(SUCCEEDED(hr)) {
9695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9696 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9697 hr = IDirect3DDevice9_EndScene(device);
9698 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9701 color = getPixelColor(device, 160, 360);
9702 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9703 color = getPixelColor(device, 480, 360);
9704 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9705 color = getPixelColor(device, 480, 120);
9706 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9707 color = getPixelColor(device, 160, 120);
9708 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9709 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9710 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9712 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9713 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9714 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9715 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9717 cleanup:
9718 if(src) IDirect3DSurface9_Release(src);
9719 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9720 if(dsttex) IDirect3DTexture9_Release(dsttex);
9723 static void texop_test(IDirect3DDevice9 *device)
9725 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9726 IDirect3DTexture9 *texture = NULL;
9727 D3DLOCKED_RECT locked_rect;
9728 D3DCOLOR color;
9729 D3DCAPS9 caps;
9730 HRESULT hr;
9731 unsigned i;
9733 static const struct {
9734 float x, y, z;
9735 float s, t;
9736 D3DCOLOR diffuse;
9737 } quad[] = {
9738 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9739 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9740 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9741 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9744 static const D3DVERTEXELEMENT9 decl_elements[] = {
9745 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9746 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9747 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9748 D3DDECL_END()
9751 static const struct {
9752 D3DTEXTUREOP op;
9753 const char *name;
9754 DWORD caps_flag;
9755 D3DCOLOR result;
9756 } test_data[] = {
9757 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9758 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9759 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9760 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9761 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9762 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9763 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9764 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9765 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9766 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9767 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9768 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9769 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9770 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9771 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9772 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9773 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9774 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9775 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9776 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9777 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9778 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9779 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9782 memset(&caps, 0, sizeof(caps));
9783 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9784 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9786 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9787 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9788 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9789 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9791 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9792 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9793 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9794 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9795 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9796 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9797 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9798 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9799 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9802 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9803 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9804 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9805 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9806 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9808 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9809 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9812 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9814 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9816 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9819 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9821 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9823 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9825 skip("tex operation %s not supported\n", test_data[i].name);
9826 continue;
9829 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9830 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9832 hr = IDirect3DDevice9_BeginScene(device);
9833 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9835 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9836 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9838 hr = IDirect3DDevice9_EndScene(device);
9839 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9841 color = getPixelColor(device, 320, 240);
9842 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9843 test_data[i].name, color, test_data[i].result);
9845 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9846 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9849 if (texture) IDirect3DTexture9_Release(texture);
9850 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9853 static void yuv_color_test(IDirect3DDevice9 *device) {
9854 HRESULT hr;
9855 IDirect3DSurface9 *surface = NULL, *target = NULL;
9856 unsigned int fmt, i;
9857 D3DFORMAT format;
9858 const char *fmt_string;
9859 D3DLOCKED_RECT lr;
9860 IDirect3D9 *d3d;
9861 HRESULT color;
9862 DWORD ref_color_left, ref_color_right;
9864 struct {
9865 DWORD in; /* The input color */
9866 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9867 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9868 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9869 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9870 } test_data[] = {
9871 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9872 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9873 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9874 * that
9876 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9877 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9878 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9879 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9880 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9881 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9882 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9883 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9884 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9885 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9886 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9887 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9888 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9889 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9891 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9892 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9893 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9894 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9897 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9898 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9899 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9900 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9902 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9903 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9905 for(fmt = 0; fmt < 2; fmt++) {
9906 if(fmt == 0) {
9907 format = D3DFMT_UYVY;
9908 fmt_string = "D3DFMT_UYVY";
9909 } else {
9910 format = D3DFMT_YUY2;
9911 fmt_string = "D3DFMT_YUY2";
9914 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9915 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9917 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9918 D3DRTYPE_SURFACE, format) != D3D_OK) {
9919 skip("%s is not supported\n", fmt_string);
9920 continue;
9923 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9924 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9925 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9927 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9928 if(fmt == 0) {
9929 ref_color_left = test_data[i].uyvy_left;
9930 ref_color_right = test_data[i].uyvy_right;
9931 } else {
9932 ref_color_left = test_data[i].yuy2_left;
9933 ref_color_right = test_data[i].yuy2_right;
9936 memset(&lr, 0, sizeof(lr));
9937 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9938 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9939 *((DWORD *) lr.pBits) = test_data[i].in;
9940 hr = IDirect3DSurface9_UnlockRect(surface);
9941 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9943 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9944 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9945 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9946 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9948 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9949 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9950 * want to add tests for the filtered pixels as well.
9952 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9953 * differently, so we need a max diff of 16
9955 color = getPixelColor(device, 40, 240);
9957 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9958 * where U != V. Skip the entire test if this bug in this case
9960 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9962 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9963 IDirect3DSurface9_Release(surface);
9964 goto out;
9967 ok(color_match(color, ref_color_left, 18),
9968 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9969 test_data[i].in, color, ref_color_left, fmt_string);
9970 color = getPixelColor(device, 600, 240);
9971 ok(color_match(color, ref_color_right, 18),
9972 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9973 test_data[i].in, color, ref_color_right, fmt_string);
9974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9975 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9977 IDirect3DSurface9_Release(surface);
9980 out:
9981 IDirect3DSurface9_Release(target);
9982 IDirect3D9_Release(d3d);
9985 static void texop_range_test(IDirect3DDevice9 *device)
9987 static const struct {
9988 float x, y, z;
9989 D3DCOLOR diffuse;
9990 } quad[] = {
9991 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9992 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9993 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9994 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9996 HRESULT hr;
9997 IDirect3DTexture9 *texture;
9998 D3DLOCKED_RECT locked_rect;
9999 D3DCAPS9 caps;
10000 DWORD color;
10002 /* We need ADD and SUBTRACT operations */
10003 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10004 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10005 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10006 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10007 return;
10009 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10010 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10011 return;
10014 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10015 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10016 /* Stage 1: result = diffuse(=1.0) + diffuse
10017 * stage 2: result = result - tfactor(= 0.5)
10019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10020 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10021 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10022 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10024 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10026 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10027 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10028 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10029 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10030 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10031 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10032 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10034 hr = IDirect3DDevice9_BeginScene(device);
10035 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10036 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10037 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10038 hr = IDirect3DDevice9_EndScene(device);
10039 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10041 color = getPixelColor(device, 320, 240);
10042 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10043 color);
10044 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10045 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10047 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10048 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10049 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10050 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10051 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10052 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10053 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10054 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10055 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10057 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10058 * stage 2: result = result + diffuse(1.0)
10060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10061 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10062 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10063 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10064 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10065 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10066 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10067 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10068 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10069 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10070 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10071 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10072 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10073 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10075 hr = IDirect3DDevice9_BeginScene(device);
10076 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10078 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10079 hr = IDirect3DDevice9_EndScene(device);
10080 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10082 color = getPixelColor(device, 320, 240);
10083 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10084 color);
10085 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10086 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10088 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10089 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10090 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10091 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10092 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10093 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10094 IDirect3DTexture9_Release(texture);
10097 static void alphareplicate_test(IDirect3DDevice9 *device) {
10098 struct vertex quad[] = {
10099 { -1.0, -1.0, 0.1, 0x80ff00ff },
10100 { 1.0, -1.0, 0.1, 0x80ff00ff },
10101 { -1.0, 1.0, 0.1, 0x80ff00ff },
10102 { 1.0, 1.0, 0.1, 0x80ff00ff },
10104 HRESULT hr;
10105 DWORD color;
10107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10108 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10110 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10111 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10113 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10114 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10115 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10118 hr = IDirect3DDevice9_BeginScene(device);
10119 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10120 if(SUCCEEDED(hr)) {
10121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10122 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10123 hr = IDirect3DDevice9_EndScene(device);
10124 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10127 color = getPixelColor(device, 320, 240);
10128 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10129 color);
10130 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10131 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10133 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10134 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10138 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10139 HRESULT hr;
10140 D3DCAPS9 caps;
10141 DWORD color;
10142 struct vertex quad[] = {
10143 { -1.0, -1.0, 0.1, 0x408080c0 },
10144 { 1.0, -1.0, 0.1, 0x408080c0 },
10145 { -1.0, 1.0, 0.1, 0x408080c0 },
10146 { 1.0, 1.0, 0.1, 0x408080c0 },
10149 memset(&caps, 0, sizeof(caps));
10150 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10151 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10152 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10153 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10154 return;
10157 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10158 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10160 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10161 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10163 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10164 * mov r0.a, diffuse.a
10165 * mov r0, r0.a
10167 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10168 * 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
10169 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10171 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10172 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10173 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10174 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10175 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10176 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10178 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10179 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10180 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10181 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10182 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10183 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10184 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10185 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10186 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10187 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10188 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10190 hr = IDirect3DDevice9_BeginScene(device);
10191 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10192 if(SUCCEEDED(hr)) {
10193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10194 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10195 hr = IDirect3DDevice9_EndScene(device);
10196 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10199 color = getPixelColor(device, 320, 240);
10200 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10201 color);
10202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10203 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10205 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10207 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10208 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10209 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10210 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10213 static void zwriteenable_test(IDirect3DDevice9 *device) {
10214 HRESULT hr;
10215 DWORD color;
10216 struct vertex quad1[] = {
10217 { -1.0, -1.0, 0.1, 0x00ff0000},
10218 { -1.0, 1.0, 0.1, 0x00ff0000},
10219 { 1.0, -1.0, 0.1, 0x00ff0000},
10220 { 1.0, 1.0, 0.1, 0x00ff0000},
10222 struct vertex quad2[] = {
10223 { -1.0, -1.0, 0.9, 0x0000ff00},
10224 { -1.0, 1.0, 0.9, 0x0000ff00},
10225 { 1.0, -1.0, 0.9, 0x0000ff00},
10226 { 1.0, 1.0, 0.9, 0x0000ff00},
10229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10230 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10232 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10233 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10235 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10237 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10239 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10241 hr = IDirect3DDevice9_BeginScene(device);
10242 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10243 if(SUCCEEDED(hr)) {
10244 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10245 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10246 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10247 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10248 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10249 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10251 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10252 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10255 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10256 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10258 hr = IDirect3DDevice9_EndScene(device);
10259 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10262 color = getPixelColor(device, 320, 240);
10263 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10264 color);
10265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10266 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10272 static void alphatest_test(IDirect3DDevice9 *device) {
10273 #define ALPHATEST_PASSED 0x0000ff00
10274 #define ALPHATEST_FAILED 0x00ff0000
10275 struct {
10276 D3DCMPFUNC func;
10277 DWORD color_less;
10278 DWORD color_equal;
10279 DWORD color_greater;
10280 } testdata[] = {
10281 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10282 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10283 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10284 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10285 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10286 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10287 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10288 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10290 unsigned int i, j;
10291 HRESULT hr;
10292 DWORD color;
10293 struct vertex quad[] = {
10294 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10295 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10296 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10297 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10299 D3DCAPS9 caps;
10301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10303 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10304 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10306 for(j = 0; j < 2; j++) {
10307 if(j == 1) {
10308 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10309 * the alpha test either for performance reasons(floating point RTs) or to work
10310 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10311 * codepath for ffp and shader in this case, and the test should cover both
10313 IDirect3DPixelShader9 *ps;
10314 DWORD shader_code[] = {
10315 0xffff0101, /* ps_1_1 */
10316 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10317 0x0000ffff /* end */
10319 memset(&caps, 0, sizeof(caps));
10320 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10321 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10322 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10323 break;
10326 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10327 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10328 IDirect3DDevice9_SetPixelShader(device, ps);
10329 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10330 IDirect3DPixelShader9_Release(ps);
10333 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10338 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10341 hr = IDirect3DDevice9_BeginScene(device);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10343 if(SUCCEEDED(hr)) {
10344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10345 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10346 hr = IDirect3DDevice9_EndScene(device);
10347 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10349 color = getPixelColor(device, 320, 240);
10350 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10351 color, testdata[i].color_less, testdata[i].func);
10352 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10353 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10355 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10356 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10358 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10359 hr = IDirect3DDevice9_BeginScene(device);
10360 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10361 if(SUCCEEDED(hr)) {
10362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10363 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10364 hr = IDirect3DDevice9_EndScene(device);
10365 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10367 color = getPixelColor(device, 320, 240);
10368 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10369 color, testdata[i].color_equal, testdata[i].func);
10370 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10371 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10374 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10376 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10377 hr = IDirect3DDevice9_BeginScene(device);
10378 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10379 if(SUCCEEDED(hr)) {
10380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10381 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10382 hr = IDirect3DDevice9_EndScene(device);
10383 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10385 color = getPixelColor(device, 320, 240);
10386 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10387 color, testdata[i].color_greater, testdata[i].func);
10388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10389 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10393 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10394 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10395 IDirect3DDevice9_SetPixelShader(device, NULL);
10396 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10399 static void sincos_test(IDirect3DDevice9 *device) {
10400 const DWORD sin_shader_code[] = {
10401 0xfffe0200, /* vs_2_0 */
10402 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10403 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10404 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10405 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10406 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10407 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10408 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10409 0x0000ffff /* end */
10411 const DWORD cos_shader_code[] = {
10412 0xfffe0200, /* vs_2_0 */
10413 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10414 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10415 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10416 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10417 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10418 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10419 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10420 0x0000ffff /* end */
10422 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10423 HRESULT hr;
10424 struct {
10425 float x, y, z;
10426 } data[1280];
10427 unsigned int i;
10428 float sincosc1[4] = {D3DSINCOSCONST1};
10429 float sincosc2[4] = {D3DSINCOSCONST2};
10431 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10432 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10434 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10435 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10436 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10437 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10438 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10439 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10440 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10441 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10442 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10443 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10445 /* Generate a point from -1 to 1 every 0.5 pixels */
10446 for(i = 0; i < 1280; i++) {
10447 data[i].x = (-640.0 + i) / 640.0;
10448 data[i].y = 0.0;
10449 data[i].z = 0.1;
10452 hr = IDirect3DDevice9_BeginScene(device);
10453 if(SUCCEEDED(hr)) {
10454 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10455 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10456 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10457 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10459 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10460 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10462 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10464 hr = IDirect3DDevice9_EndScene(device);
10465 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10467 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10468 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10469 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10471 IDirect3DDevice9_SetVertexShader(device, NULL);
10472 IDirect3DVertexShader9_Release(sin_shader);
10473 IDirect3DVertexShader9_Release(cos_shader);
10476 static void loop_index_test(IDirect3DDevice9 *device) {
10477 const DWORD shader_code[] = {
10478 0xfffe0200, /* vs_2_0 */
10479 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10480 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10481 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10482 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10483 0x0000001d, /* endloop */
10484 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10485 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10486 0x0000ffff /* END */
10488 IDirect3DVertexShader9 *shader;
10489 HRESULT hr;
10490 DWORD color;
10491 const float quad[] = {
10492 -1.0, -1.0, 0.1,
10493 1.0, -1.0, 0.1,
10494 -1.0, 1.0, 0.1,
10495 1.0, 1.0, 0.1
10497 const float zero[4] = {0, 0, 0, 0};
10498 const float one[4] = {1, 1, 1, 1};
10499 int i0[4] = {2, 10, -3, 0};
10500 float values[4];
10502 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10503 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10504 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10505 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10506 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10507 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10508 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10509 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10511 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10512 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10513 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10514 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10515 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10516 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10517 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10518 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10519 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10520 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10521 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10522 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10523 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10524 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10525 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10526 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10527 values[0] = 1.0;
10528 values[1] = 1.0;
10529 values[2] = 0.0;
10530 values[3] = 0.0;
10531 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10532 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10533 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10534 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10535 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10536 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10537 values[0] = -1.0;
10538 values[1] = 0.0;
10539 values[2] = 0.0;
10540 values[3] = 0.0;
10541 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10542 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10543 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10544 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10545 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10546 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10547 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10548 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10549 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10550 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10552 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10553 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10555 hr = IDirect3DDevice9_BeginScene(device);
10556 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10557 if(SUCCEEDED(hr))
10559 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10560 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10561 hr = IDirect3DDevice9_EndScene(device);
10562 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10564 color = getPixelColor(device, 320, 240);
10565 ok(color_match(color, 0x0000ff00, 1),
10566 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10568 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10570 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10571 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10572 IDirect3DVertexShader9_Release(shader);
10575 static void sgn_test(IDirect3DDevice9 *device) {
10576 const DWORD shader_code[] = {
10577 0xfffe0200, /* vs_2_0 */
10578 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10579 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10580 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10581 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10582 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10583 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10584 0x0000ffff /* end */
10586 IDirect3DVertexShader9 *shader;
10587 HRESULT hr;
10588 DWORD color;
10589 const float quad[] = {
10590 -1.0, -1.0, 0.1,
10591 1.0, -1.0, 0.1,
10592 -1.0, 1.0, 0.1,
10593 1.0, 1.0, 0.1
10596 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10597 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10598 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10599 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10600 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10601 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10603 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10605 hr = IDirect3DDevice9_BeginScene(device);
10606 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10607 if(SUCCEEDED(hr))
10609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10610 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10611 hr = IDirect3DDevice9_EndScene(device);
10612 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10614 color = getPixelColor(device, 320, 240);
10615 ok(color_match(color, 0x008000ff, 1),
10616 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10618 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10620 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10621 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10622 IDirect3DVertexShader9_Release(shader);
10625 static void viewport_test(IDirect3DDevice9 *device) {
10626 HRESULT hr;
10627 DWORD color;
10628 D3DVIEWPORT9 vp, old_vp;
10629 BOOL draw_failed = TRUE;
10630 const float quad[] =
10632 -0.5, -0.5, 0.1,
10633 0.5, -0.5, 0.1,
10634 -0.5, 0.5, 0.1,
10635 0.5, 0.5, 0.1
10638 memset(&old_vp, 0, sizeof(old_vp));
10639 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10640 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10643 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10645 /* Test a viewport with Width and Height bigger than the surface dimensions
10647 * TODO: Test Width < surface.width, but X + Width > surface.width
10648 * TODO: Test Width < surface.width, what happens with the height?
10650 * The expected behavior is that the viewport behaves like the "default"
10651 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10652 * MinZ = 0.0, MaxZ = 1.0.
10654 * Starting with Windows 7 the behavior among driver versions is not
10655 * consistent. The SetViewport call is accepted on all drivers. Some
10656 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10657 * nvidia drivers draw, but use the actual values in the viewport and only
10658 * display the upper left part on the surface.
10660 memset(&vp, 0, sizeof(vp));
10661 vp.X = 0;
10662 vp.Y = 0;
10663 vp.Width = 10000;
10664 vp.Height = 10000;
10665 vp.MinZ = 0.0;
10666 vp.MaxZ = 0.0;
10667 hr = IDirect3DDevice9_SetViewport(device, &vp);
10668 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10672 hr = IDirect3DDevice9_BeginScene(device);
10673 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10674 if(SUCCEEDED(hr))
10676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10677 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10678 draw_failed = FAILED(hr);
10679 hr = IDirect3DDevice9_EndScene(device);
10680 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10683 if(!draw_failed)
10685 color = getPixelColor(device, 158, 118);
10686 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10687 color = getPixelColor(device, 162, 118);
10688 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10689 color = getPixelColor(device, 158, 122);
10690 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10691 color = getPixelColor(device, 162, 122);
10692 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10694 color = getPixelColor(device, 478, 358);
10695 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10696 color = getPixelColor(device, 482, 358);
10697 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10698 color = getPixelColor(device, 478, 362);
10699 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10700 color = getPixelColor(device, 482, 362);
10701 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10704 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10705 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10707 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10708 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10711 /* This test tests depth clamping / clipping behaviour:
10712 * - With software vertex processing, depth values are clamped to the
10713 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10714 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10715 * same as regular vertices here.
10716 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10717 * Normal vertices are always clipped. Pretransformed vertices are
10718 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10719 * - The viewport's MinZ/MaxZ is irrelevant for this.
10721 static void depth_clamp_test(IDirect3DDevice9 *device)
10723 const struct tvertex quad1[] =
10725 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10726 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10727 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10728 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10730 const struct tvertex quad2[] =
10732 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10733 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10734 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10735 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10737 const struct tvertex quad3[] =
10739 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10740 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10741 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10742 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10744 const struct tvertex quad4[] =
10746 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10747 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10748 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10749 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10751 const struct vertex quad5[] =
10753 { -0.5f, 0.5f, 10.0f, 0xff14f914},
10754 { 0.5f, 0.5f, 10.0f, 0xff14f914},
10755 { -0.5f, -0.5f, 10.0f, 0xff14f914},
10756 { 0.5f, -0.5f, 10.0f, 0xff14f914},
10758 const struct vertex quad6[] =
10760 { -1.0f, 0.5f, 10.0f, 0xfff91414},
10761 { 1.0f, 0.5f, 10.0f, 0xfff91414},
10762 { -1.0f, 0.25f, 10.0f, 0xfff91414},
10763 { 1.0f, 0.25f, 10.0f, 0xfff91414},
10766 D3DVIEWPORT9 vp;
10767 D3DCOLOR color;
10768 D3DCAPS9 caps;
10769 HRESULT hr;
10771 vp.X = 0;
10772 vp.Y = 0;
10773 vp.Width = 640;
10774 vp.Height = 480;
10775 vp.MinZ = 0.0;
10776 vp.MaxZ = 7.5;
10778 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10779 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10781 hr = IDirect3DDevice9_SetViewport(device, &vp);
10782 if(FAILED(hr))
10784 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10785 * the tests because the 7.5 is just intended to show that it doesn't have
10786 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10787 * viewport and continue.
10789 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10790 vp.MaxZ = 1.0;
10791 hr = IDirect3DDevice9_SetViewport(device, &vp);
10793 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10796 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10799 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10801 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10803 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10805 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10807 hr = IDirect3DDevice9_BeginScene(device);
10808 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10810 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10811 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10816 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10819 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10824 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10827 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10829 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10830 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10833 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10836 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10839 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10841 hr = IDirect3DDevice9_EndScene(device);
10842 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10844 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10846 color = getPixelColor(device, 75, 75);
10847 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10848 color = getPixelColor(device, 150, 150);
10849 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10850 color = getPixelColor(device, 320, 240);
10851 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10852 color = getPixelColor(device, 320, 330);
10853 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10854 color = getPixelColor(device, 320, 330);
10855 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10857 else
10859 color = getPixelColor(device, 75, 75);
10860 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10861 color = getPixelColor(device, 150, 150);
10862 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10863 color = getPixelColor(device, 320, 240);
10864 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10865 color = getPixelColor(device, 320, 330);
10866 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10867 color = getPixelColor(device, 320, 330);
10868 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10872 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10874 vp.MinZ = 0.0;
10875 vp.MaxZ = 1.0;
10876 hr = IDirect3DDevice9_SetViewport(device, &vp);
10877 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10880 static void depth_bounds_test(IDirect3DDevice9 *device)
10882 const struct tvertex quad1[] =
10884 { 0, 0, 0.0f, 1, 0xfff9e814},
10885 { 640, 0, 0.0f, 1, 0xfff9e814},
10886 { 0, 480, 1.0f, 1, 0xfff9e814},
10887 { 640, 480, 1.0f, 1, 0xfff9e814},
10889 const struct tvertex quad2[] =
10891 { 0, 0, 0.6f, 1, 0xff002b7f},
10892 { 640, 0, 0.6f, 1, 0xff002b7f},
10893 { 0, 480, 0.6f, 1, 0xff002b7f},
10894 { 640, 480, 0.6f, 1, 0xff002b7f},
10896 const struct tvertex quad3[] =
10898 { 0, 100, 0.6f, 1, 0xfff91414},
10899 { 640, 100, 0.6f, 1, 0xfff91414},
10900 { 0, 160, 0.6f, 1, 0xfff91414},
10901 { 640, 160, 0.6f, 1, 0xfff91414},
10904 union {
10905 DWORD d;
10906 float f;
10907 } tmpvalue;
10909 IDirect3D9 *d3d = NULL;
10910 IDirect3DSurface9 *offscreen_surface = NULL;
10911 D3DCOLOR color;
10912 HRESULT hr;
10914 IDirect3DDevice9_GetDirect3D(device, &d3d);
10915 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10916 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10917 skip("No NVDB (depth bounds test) support\n");
10918 IDirect3D9_Release(d3d);
10919 return;
10921 IDirect3D9_Release(d3d);
10923 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10924 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10925 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10926 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10928 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10929 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10932 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10934 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10936 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10938 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10941 hr = IDirect3DDevice9_BeginScene(device);
10942 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10944 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10945 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10948 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10951 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10953 tmpvalue.f = 0.625;
10954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10955 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10957 tmpvalue.f = 0.75;
10958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10959 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10962 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10964 tmpvalue.f = 0.75;
10965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10966 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10972 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10974 hr = IDirect3DDevice9_EndScene(device);
10975 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10977 color = getPixelColor(device, 150, 130);
10978 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10979 color = getPixelColor(device, 150, 200);
10980 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10981 color = getPixelColor(device, 150, 300-5);
10982 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10983 color = getPixelColor(device, 150, 300+5);
10984 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10985 color = getPixelColor(device, 150, 330);
10986 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10987 color = getPixelColor(device, 150, 360-5);
10988 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10989 color = getPixelColor(device, 150, 360+5);
10990 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10993 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10996 static void depth_buffer_test(IDirect3DDevice9 *device)
10998 static const struct vertex quad1[] =
11000 { -1.0, 1.0, 0.33f, 0xff00ff00},
11001 { 1.0, 1.0, 0.33f, 0xff00ff00},
11002 { -1.0, -1.0, 0.33f, 0xff00ff00},
11003 { 1.0, -1.0, 0.33f, 0xff00ff00},
11005 static const struct vertex quad2[] =
11007 { -1.0, 1.0, 0.50f, 0xffff00ff},
11008 { 1.0, 1.0, 0.50f, 0xffff00ff},
11009 { -1.0, -1.0, 0.50f, 0xffff00ff},
11010 { 1.0, -1.0, 0.50f, 0xffff00ff},
11012 static const struct vertex quad3[] =
11014 { -1.0, 1.0, 0.66f, 0xffff0000},
11015 { 1.0, 1.0, 0.66f, 0xffff0000},
11016 { -1.0, -1.0, 0.66f, 0xffff0000},
11017 { 1.0, -1.0, 0.66f, 0xffff0000},
11019 static const DWORD expected_colors[4][4] =
11021 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11022 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11023 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11024 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11027 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11028 unsigned int i, j;
11029 D3DVIEWPORT9 vp;
11030 D3DCOLOR color;
11031 HRESULT hr;
11033 vp.X = 0;
11034 vp.Y = 0;
11035 vp.Width = 640;
11036 vp.Height = 480;
11037 vp.MinZ = 0.0;
11038 vp.MaxZ = 1.0;
11040 hr = IDirect3DDevice9_SetViewport(device, &vp);
11041 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11044 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11046 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11048 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11050 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11051 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11052 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11054 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11055 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11056 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11057 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11058 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11059 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11060 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11061 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11062 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11063 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11064 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11066 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11067 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11069 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11071 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11072 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11073 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11074 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11076 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11077 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11078 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11079 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11081 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11082 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11083 hr = IDirect3DDevice9_BeginScene(device);
11084 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11086 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11087 hr = IDirect3DDevice9_EndScene(device);
11088 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11090 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11091 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11092 IDirect3DSurface9_Release(backbuffer);
11093 IDirect3DSurface9_Release(rt3);
11094 IDirect3DSurface9_Release(rt2);
11095 IDirect3DSurface9_Release(rt1);
11097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11098 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11100 hr = IDirect3DDevice9_BeginScene(device);
11101 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11104 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11105 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11106 hr = IDirect3DDevice9_EndScene(device);
11107 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11109 for (i = 0; i < 4; ++i)
11111 for (j = 0; j < 4; ++j)
11113 unsigned int x = 80 * ((2 * j) + 1);
11114 unsigned int y = 60 * ((2 * i) + 1);
11115 color = getPixelColor(device, x, y);
11116 ok(color_match(color, expected_colors[i][j], 0),
11117 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11121 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11122 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11125 /* Test that partial depth copies work the way they're supposed to. The clear
11126 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11127 * the following draw should only copy back the part that was modified. */
11128 static void depth_buffer2_test(IDirect3DDevice9 *device)
11130 static const struct vertex quad[] =
11132 { -1.0, 1.0, 0.66f, 0xffff0000},
11133 { 1.0, 1.0, 0.66f, 0xffff0000},
11134 { -1.0, -1.0, 0.66f, 0xffff0000},
11135 { 1.0, -1.0, 0.66f, 0xffff0000},
11138 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11139 unsigned int i, j;
11140 D3DVIEWPORT9 vp;
11141 D3DCOLOR color;
11142 HRESULT hr;
11144 vp.X = 0;
11145 vp.Y = 0;
11146 vp.Width = 640;
11147 vp.Height = 480;
11148 vp.MinZ = 0.0;
11149 vp.MaxZ = 1.0;
11151 hr = IDirect3DDevice9_SetViewport(device, &vp);
11152 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11155 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11157 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11159 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11161 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11163 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11165 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11166 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11167 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11168 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11169 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11170 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11171 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11172 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11174 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11175 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11176 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11177 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11179 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11180 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11182 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11184 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11185 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11186 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11187 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11189 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11190 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11191 IDirect3DSurface9_Release(backbuffer);
11192 IDirect3DSurface9_Release(rt2);
11193 IDirect3DSurface9_Release(rt1);
11195 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11196 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11198 hr = IDirect3DDevice9_BeginScene(device);
11199 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11200 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11201 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11202 hr = IDirect3DDevice9_EndScene(device);
11203 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11205 for (i = 0; i < 4; ++i)
11207 for (j = 0; j < 4; ++j)
11209 unsigned int x = 80 * ((2 * j) + 1);
11210 unsigned int y = 60 * ((2 * i) + 1);
11211 color = getPixelColor(device, x, y);
11212 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11213 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11217 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11218 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11221 static void depth_blit_test(IDirect3DDevice9 *device)
11223 static const struct vertex quad1[] =
11225 { -1.0, 1.0, 0.50f, 0xff00ff00},
11226 { 1.0, 1.0, 0.50f, 0xff00ff00},
11227 { -1.0, -1.0, 0.50f, 0xff00ff00},
11228 { 1.0, -1.0, 0.50f, 0xff00ff00},
11230 static const struct vertex quad2[] =
11232 { -1.0, 1.0, 0.66f, 0xff0000ff},
11233 { 1.0, 1.0, 0.66f, 0xff0000ff},
11234 { -1.0, -1.0, 0.66f, 0xff0000ff},
11235 { 1.0, -1.0, 0.66f, 0xff0000ff},
11237 static const DWORD expected_colors[4][4] =
11239 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11240 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11241 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11242 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11245 IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11246 RECT src_rect, dst_rect;
11247 unsigned int i, j;
11248 D3DVIEWPORT9 vp;
11249 D3DCOLOR color;
11250 HRESULT hr;
11252 vp.X = 0;
11253 vp.Y = 0;
11254 vp.Width = 640;
11255 vp.Height = 480;
11256 vp.MinZ = 0.0;
11257 vp.MaxZ = 1.0;
11259 hr = IDirect3DDevice9_SetViewport(device, &vp);
11260 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11262 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11263 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11264 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11265 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11266 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11267 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11268 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11269 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11272 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11274 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11276 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11277 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11278 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11281 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11282 SetRect(&dst_rect, 0, 0, 480, 360);
11283 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11284 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11285 SetRect(&dst_rect, 0, 0, 320, 240);
11286 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11287 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11289 /* Partial blit. */
11290 SetRect(&src_rect, 0, 0, 320, 240);
11291 SetRect(&dst_rect, 0, 0, 320, 240);
11292 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11293 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11294 /* Flipped. */
11295 SetRect(&src_rect, 0, 0, 640, 480);
11296 SetRect(&dst_rect, 0, 480, 640, 0);
11297 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11298 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11299 /* Full, explicit. */
11300 SetRect(&src_rect, 0, 0, 640, 480);
11301 SetRect(&dst_rect, 0, 0, 640, 480);
11302 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11303 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11304 /* Filtered blit. */
11305 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11306 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11307 /* Depth -> color blit.*/
11308 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11309 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11310 IDirect3DSurface9_Release(backbuffer);
11312 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11313 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11315 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11316 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11317 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11318 IDirect3DSurface9_Release(ds2);
11319 IDirect3DSurface9_Release(ds1);
11321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11322 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11323 hr = IDirect3DDevice9_BeginScene(device);
11324 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11326 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11328 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11329 hr = IDirect3DDevice9_EndScene(device);
11330 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11332 for (i = 0; i < 4; ++i)
11334 for (j = 0; j < 4; ++j)
11336 unsigned int x = 80 * ((2 * j) + 1);
11337 unsigned int y = 60 * ((2 * i) + 1);
11338 color = getPixelColor(device, x, y);
11339 ok(color_match(color, expected_colors[i][j], 0),
11340 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11344 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11345 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11348 static void intz_test(IDirect3DDevice9 *device)
11350 static const DWORD ps_code[] =
11352 0xffff0200, /* ps_2_0 */
11353 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11354 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11355 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11356 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11357 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11358 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11359 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11360 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11361 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11362 0x0000ffff, /* end */
11364 struct
11366 float x, y, z;
11367 float s, t, p, q;
11369 quad[] =
11371 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11372 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11373 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11374 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11376 struct
11378 UINT x, y;
11379 D3DCOLOR color;
11381 expected_colors[] =
11383 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11384 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11385 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11386 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11387 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11388 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11389 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11390 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11393 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11394 IDirect3DTexture9 *texture;
11395 IDirect3DPixelShader9 *ps;
11396 IDirect3DSurface9 *ds;
11397 IDirect3D9 *d3d9;
11398 D3DCAPS9 caps;
11399 HRESULT hr;
11400 UINT i;
11402 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11403 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11404 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11406 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11407 return;
11410 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11411 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11413 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11414 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11415 if (FAILED(hr))
11417 skip("No INTZ support, skipping INTZ test.\n");
11418 return;
11421 IDirect3D9_Release(d3d9);
11423 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11424 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11425 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11426 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11428 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11429 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11430 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11431 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11432 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11433 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11434 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11435 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11437 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11438 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11440 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11442 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11444 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11446 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11448 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11449 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11450 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11451 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11452 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11453 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11454 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11455 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11456 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11457 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11459 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11460 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11461 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11462 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11463 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11464 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11465 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11466 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11468 /* Setup the depth/stencil surface. */
11469 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11470 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11472 hr = IDirect3DDevice9_BeginScene(device);
11473 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11475 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11476 hr = IDirect3DDevice9_EndScene(device);
11477 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11479 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11480 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11481 IDirect3DSurface9_Release(ds);
11482 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11483 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11484 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11485 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11486 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11487 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11489 /* Read the depth values back. */
11490 hr = IDirect3DDevice9_BeginScene(device);
11491 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11492 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11493 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11494 hr = IDirect3DDevice9_EndScene(device);
11495 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11497 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11499 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11500 ok(color_match(color, expected_colors[i].color, 1),
11501 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11502 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11505 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11506 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11508 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11509 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11510 IDirect3DSurface9_Release(original_ds);
11511 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11512 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11513 IDirect3DTexture9_Release(texture);
11514 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11515 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11516 IDirect3DPixelShader9_Release(ps);
11518 IDirect3DSurface9_Release(original_rt);
11519 IDirect3DSurface9_Release(rt);
11522 static void shadow_test(IDirect3DDevice9 *device)
11524 static const DWORD ps_code[] =
11526 0xffff0200, /* ps_2_0 */
11527 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11528 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11529 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11530 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11531 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11532 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11533 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11534 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11535 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11536 0x0000ffff, /* end */
11538 struct
11540 D3DFORMAT format;
11541 const char *name;
11543 formats[] =
11545 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11546 {D3DFMT_D32, "D3DFMT_D32"},
11547 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11548 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11549 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11550 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11551 {D3DFMT_D16, "D3DFMT_D16"},
11552 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11553 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11555 struct
11557 float x, y, z;
11558 float s, t, p, q;
11560 quad[] =
11562 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11563 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11564 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11565 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11567 struct
11569 UINT x, y;
11570 D3DCOLOR color;
11572 expected_colors[] =
11574 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11575 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11576 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11577 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11578 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11579 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11580 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11581 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11584 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11585 IDirect3DPixelShader9 *ps;
11586 IDirect3D9 *d3d9;
11587 D3DCAPS9 caps;
11588 HRESULT hr;
11589 UINT i;
11591 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11592 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11593 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11595 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11596 return;
11599 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11600 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11601 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11602 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11603 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11604 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11606 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11607 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11608 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11609 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11610 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11612 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11613 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11615 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11617 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11619 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11621 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11623 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11624 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11625 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11626 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11627 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11628 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11629 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11630 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11631 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11632 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11634 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11636 D3DFORMAT format = formats[i].format;
11637 IDirect3DTexture9 *texture;
11638 IDirect3DSurface9 *ds;
11639 unsigned int j;
11641 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11642 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11643 if (FAILED(hr)) continue;
11645 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11646 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11647 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11649 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11650 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11652 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11653 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11655 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11656 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11658 IDirect3DDevice9_SetPixelShader(device, NULL);
11659 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11661 /* Setup the depth/stencil surface. */
11662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11663 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11665 hr = IDirect3DDevice9_BeginScene(device);
11666 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11667 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11668 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11669 hr = IDirect3DDevice9_EndScene(device);
11670 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11672 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11673 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11674 IDirect3DSurface9_Release(ds);
11676 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11677 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11679 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11680 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11682 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11683 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11685 /* Do the actual shadow mapping. */
11686 hr = IDirect3DDevice9_BeginScene(device);
11687 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11689 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11690 hr = IDirect3DDevice9_EndScene(device);
11691 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11693 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11694 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11695 IDirect3DTexture9_Release(texture);
11697 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11699 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11700 ok(color_match(color, expected_colors[j].color, 0),
11701 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11702 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11703 formats[i].name, color);
11706 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11707 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11710 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11711 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11712 IDirect3DPixelShader9_Release(ps);
11714 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11715 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11716 IDirect3DSurface9_Release(original_ds);
11718 IDirect3DSurface9_Release(original_rt);
11719 IDirect3DSurface9_Release(rt);
11721 IDirect3D9_Release(d3d9);
11724 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11726 const struct vertex quad1[] =
11728 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11729 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11730 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
11731 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
11733 const struct vertex quad2[] =
11735 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11736 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11737 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
11738 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
11740 D3DCOLOR color;
11741 HRESULT hr;
11743 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11744 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11746 hr = IDirect3DDevice9_BeginScene(device);
11747 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11749 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11750 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11753 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11755 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11758 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11760 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11762 hr = IDirect3DDevice9_EndScene(device);
11763 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11765 color = getPixelColor(device, 1, 240);
11766 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11767 color = getPixelColor(device, 638, 240);
11768 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11770 color = getPixelColor(device, 1, 241);
11771 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11772 color = getPixelColor(device, 638, 241);
11773 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11776 static void clip_planes_test(IDirect3DDevice9 *device)
11778 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11780 const DWORD shader_code[] = {
11781 0xfffe0200, /* vs_2_0 */
11782 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11783 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11784 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11785 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11786 0x0000ffff /* end */
11788 IDirect3DVertexShader9 *shader;
11790 IDirect3DTexture9 *offscreen = NULL;
11791 IDirect3DSurface9 *offscreen_surface, *original_rt;
11792 HRESULT hr;
11794 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11795 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11797 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11798 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11800 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11802 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11804 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11806 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11807 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11808 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11809 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11811 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11813 clip_planes(device, "Onscreen FFP");
11815 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11816 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11817 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11818 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11819 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11820 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11822 clip_planes(device, "Offscreen FFP");
11824 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11825 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11827 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11828 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11829 IDirect3DDevice9_SetVertexShader(device, shader);
11830 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11832 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11833 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11835 clip_planes(device, "Onscreen vertex shader");
11837 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11838 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11840 clip_planes(device, "Offscreen vertex shader");
11842 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11843 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11845 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11846 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11847 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11848 IDirect3DVertexShader9_Release(shader);
11849 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11851 IDirect3DSurface9_Release(original_rt);
11852 IDirect3DSurface9_Release(offscreen_surface);
11853 IDirect3DTexture9_Release(offscreen);
11856 static void fp_special_test(IDirect3DDevice9 *device)
11858 static const DWORD vs_header[] =
11860 0xfffe0200, /* vs_2_0 */
11861 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11862 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11863 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11866 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11867 static const DWORD vs_pow[] =
11868 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11869 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11870 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11871 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11872 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11873 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11874 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
11875 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
11877 static const DWORD vs_footer[] =
11879 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11880 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11881 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11882 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11883 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11884 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11885 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11886 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11887 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11888 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11889 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11890 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11891 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11892 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11893 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11894 0x0000ffff, /* end */
11897 static const struct
11899 const char *name;
11900 const DWORD *ops;
11901 DWORD size;
11902 D3DCOLOR r600;
11903 D3DCOLOR nv40;
11904 D3DCOLOR nv50;
11906 vs_body[] =
11908 /* The basic ideas here are:
11909 * 2.0 * +/-INF == +/-INF
11910 * NAN != NAN
11912 * The vertex shader value is written to the red component, with 0.0
11913 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11914 * result in 0x00. The pixel shader value is written to the green
11915 * component, but here 0.0 also results in 0x00. The actual value is
11916 * written to the blue component.
11918 * There are considerable differences between graphics cards in how
11919 * these are handled, but pow and nrm never generate INF or NAN. */
11920 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
11921 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
11922 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
11923 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11924 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
11925 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11926 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11927 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000},
11930 static const DWORD ps_code[] =
11932 0xffff0200, /* ps_2_0 */
11933 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11934 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11935 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11936 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11937 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11938 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11939 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11940 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11941 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11942 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11943 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11944 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11945 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11946 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11947 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11948 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11949 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11950 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11951 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11952 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11953 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11954 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11955 0x0000ffff, /* end */
11958 struct
11960 float x, y, z;
11961 float s;
11963 quad[] =
11965 { -1.0f, 1.0f, 0.0f, 0.0f},
11966 { 1.0f, 1.0f, 1.0f, 0.0f},
11967 { -1.0f, -1.0f, 0.0f, 0.0f},
11968 { 1.0f, -1.0f, 1.0f, 0.0f},
11971 IDirect3DPixelShader9 *ps;
11972 UINT body_size = 0;
11973 DWORD *vs_code;
11974 D3DCAPS9 caps;
11975 HRESULT hr;
11976 UINT i;
11978 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11979 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11980 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11982 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11983 return;
11986 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11987 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11989 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11990 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11991 IDirect3DDevice9_SetPixelShader(device, ps);
11992 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11995 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11998 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12000 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12002 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12005 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12006 memcpy(vs_code, vs_header, sizeof(vs_header));
12008 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12010 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12011 IDirect3DVertexShader9 *vs;
12012 D3DCOLOR color;
12014 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12015 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12016 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12018 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12019 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12020 IDirect3DDevice9_SetVertexShader(device, vs);
12021 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12023 hr = IDirect3DDevice9_BeginScene(device);
12024 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12026 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12027 hr = IDirect3DDevice9_EndScene(device);
12028 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12030 color = getPixelColor(device, 320, 240);
12031 ok(color_match(color, vs_body[i].r600, 1)
12032 || color_match(color, vs_body[i].nv40, 1)
12033 || color_match(color, vs_body[i].nv50, 1),
12034 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12035 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12037 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12038 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12040 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12041 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12042 IDirect3DVertexShader9_Release(vs);
12045 HeapFree(GetProcessHeap(), 0, vs_code);
12047 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12048 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12049 IDirect3DPixelShader9_Release(ps);
12052 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12054 IDirect3D9 *d3d;
12055 IDirect3DSurface9 *rt, *backbuffer;
12056 IDirect3DTexture9 *texture;
12057 HRESULT hr;
12058 int i;
12059 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12060 static const struct
12062 D3DFORMAT fmt;
12063 const char *name;
12065 formats[] =
12067 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12068 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12069 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12070 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12071 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12073 static const struct
12075 float x, y, z;
12076 float u, v;
12078 quad[] =
12080 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12081 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12082 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12083 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12086 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12087 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12088 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12089 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12090 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12091 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12092 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12093 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12095 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12097 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12099 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12100 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12102 skip("Format %s not supported as render target, skipping test.\n",
12103 formats[i].name);
12104 continue;
12107 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12108 D3DPOOL_DEFAULT, &texture, NULL);
12109 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12111 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12113 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12114 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12115 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12116 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12118 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12120 hr = IDirect3DDevice9_BeginScene(device);
12121 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12122 if(SUCCEEDED(hr))
12124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12125 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12126 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12127 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12129 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12132 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12133 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12134 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12135 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12136 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12137 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12138 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12140 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12141 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12142 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12144 hr = IDirect3DDevice9_EndScene(device);
12145 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12148 IDirect3DSurface9_Release(rt);
12149 IDirect3DTexture9_Release(texture);
12151 color = getPixelColor(device, 360, 240);
12152 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12153 D3DUSAGE_QUERY_SRGBWRITE,
12154 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12156 /* Big slop for R5G6B5 */
12157 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12158 formats[i].name, color_srgb, color);
12160 else
12162 /* Big slop for R5G6B5 */
12163 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12164 formats[i].name, color_rgb, color);
12167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12168 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12171 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12172 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12174 IDirect3D9_Release(d3d);
12175 IDirect3DSurface9_Release(backbuffer);
12178 static void ds_size_test(IDirect3DDevice9 *device)
12180 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12181 HRESULT hr;
12182 DWORD num_passes;
12183 struct
12185 float x, y, z;
12187 quad[] =
12189 {-1.0, -1.0, 0.0 },
12190 {-1.0, 1.0, 0.0 },
12191 { 1.0, -1.0, 0.0 },
12192 { 1.0, 1.0, 0.0 }
12195 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12196 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12197 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12198 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12199 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12200 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12203 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12205 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12207 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12208 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12209 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12210 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12211 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12212 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12213 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12214 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12216 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12217 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12218 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12219 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12221 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12222 * but does not change the surface's contents. */
12223 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12224 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12226 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12227 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12228 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12230 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12232 /* Turning on any depth-related state results in a ValidateDevice failure */
12233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12234 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12235 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12236 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12237 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, 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);
12246 /* Try to draw with the device in an invalid state */
12247 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12249 hr = IDirect3DDevice9_BeginScene(device);
12250 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12251 if(SUCCEEDED(hr))
12253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12254 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12255 hr = IDirect3DDevice9_EndScene(device);
12256 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12258 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12259 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12260 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12263 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12264 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12265 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12266 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12267 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12268 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12270 IDirect3DSurface9_Release(readback);
12271 IDirect3DSurface9_Release(ds);
12272 IDirect3DSurface9_Release(rt);
12273 IDirect3DSurface9_Release(old_rt);
12274 IDirect3DSurface9_Release(old_ds);
12277 static void unbound_sampler_test(IDirect3DDevice9 *device)
12279 HRESULT hr;
12280 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12281 IDirect3DSurface9 *rt, *old_rt;
12282 DWORD color;
12284 static const DWORD ps_code[] =
12286 0xffff0200, /* ps_2_0 */
12287 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12288 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12289 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12290 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12291 0x0000ffff, /* end */
12293 static const DWORD ps_code_cube[] =
12295 0xffff0200, /* ps_2_0 */
12296 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
12297 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12298 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12299 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12300 0x0000ffff, /* end */
12302 static const DWORD ps_code_volume[] =
12304 0xffff0200, /* ps_2_0 */
12305 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
12306 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12307 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12308 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12309 0x0000ffff, /* end */
12312 static const struct
12314 float x, y, z;
12315 float u, v;
12317 quad[] =
12319 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12320 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12321 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12322 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12325 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12326 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12328 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12329 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12330 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12331 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12332 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12333 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12335 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12336 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12338 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12339 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12341 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12342 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12344 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12345 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12347 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12348 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12350 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12351 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12353 hr = IDirect3DDevice9_BeginScene(device);
12354 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12355 if(SUCCEEDED(hr))
12357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12358 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12360 hr = IDirect3DDevice9_EndScene(device);
12361 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12364 color = getPixelColorFromSurface(rt, 32, 32);
12365 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12367 /* Now try with a cube texture */
12368 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12369 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12371 hr = IDirect3DDevice9_BeginScene(device);
12372 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12373 if (SUCCEEDED(hr))
12375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12376 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12378 hr = IDirect3DDevice9_EndScene(device);
12379 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12382 color = getPixelColorFromSurface(rt, 32, 32);
12383 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12385 /* And then with a volume texture */
12386 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12387 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12389 hr = IDirect3DDevice9_BeginScene(device);
12390 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12391 if (SUCCEEDED(hr))
12393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12394 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12396 hr = IDirect3DDevice9_EndScene(device);
12397 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12400 color = getPixelColorFromSurface(rt, 32, 32);
12401 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12403 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12404 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12406 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12407 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12409 IDirect3DSurface9_Release(rt);
12410 IDirect3DSurface9_Release(old_rt);
12411 IDirect3DPixelShader9_Release(ps);
12412 IDirect3DPixelShader9_Release(ps_cube);
12413 IDirect3DPixelShader9_Release(ps_volume);
12416 static void update_surface_test(IDirect3DDevice9 *device)
12418 static const BYTE blocks[][8] =
12420 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12421 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12422 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12423 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12424 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12425 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12426 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12428 static const struct
12430 UINT x, y;
12431 D3DCOLOR color;
12433 expected_colors[] =
12435 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12436 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12437 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12438 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12439 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12440 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12441 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12443 static const struct
12445 float x, y, z, w;
12446 float u, v;
12448 tri[] =
12450 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12451 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12452 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12454 static const RECT rect_2x2 = {0, 0, 2, 2};
12455 static const struct
12457 UINT src_level;
12458 UINT dst_level;
12459 const RECT *r;
12460 HRESULT hr;
12462 block_size_tests[] =
12464 {1, 0, NULL, D3D_OK},
12465 {0, 1, NULL, D3DERR_INVALIDCALL},
12466 {5, 4, NULL, D3DERR_INVALIDCALL},
12467 {4, 5, NULL, D3DERR_INVALIDCALL},
12468 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12469 {5, 5, &rect_2x2, D3D_OK},
12472 IDirect3DSurface9 *src_surface, *dst_surface;
12473 IDirect3DTexture9 *src_tex, *dst_tex;
12474 IDirect3D9 *d3d;
12475 UINT count, i;
12476 HRESULT hr;
12478 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12479 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12481 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12482 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12483 IDirect3D9_Release(d3d);
12484 if (FAILED(hr))
12486 skip("DXT1 not supported, skipping test.\n");
12487 return;
12490 IDirect3D9_Release(d3d);
12492 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12493 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12494 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12495 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12497 count = IDirect3DTexture9_GetLevelCount(src_tex);
12498 ok(count == 7, "Got level count %u, expected 7.\n", count);
12500 for (i = 0; i < count; ++i)
12502 UINT row_count, block_count, x, y;
12503 D3DSURFACE_DESC desc;
12504 BYTE *row, *block;
12505 D3DLOCKED_RECT r;
12507 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12508 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12510 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12511 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12513 row_count = ((desc.Height + 3) & ~3) / 4;
12514 block_count = ((desc.Width + 3) & ~3) / 4;
12515 row = r.pBits;
12517 for (y = 0; y < row_count; ++y)
12519 block = row;
12520 for (x = 0; x < block_count; ++x)
12522 memcpy(block, blocks[i], sizeof(blocks[i]));
12523 block += sizeof(blocks[i]);
12525 row += r.Pitch;
12528 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12529 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12532 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12534 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12535 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12536 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12537 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12539 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12540 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12541 hr, i, block_size_tests[i].hr);
12543 IDirect3DSurface9_Release(dst_surface);
12544 IDirect3DSurface9_Release(src_surface);
12547 for (i = 0; i < count; ++i)
12549 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12550 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12551 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12552 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12554 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12555 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12557 IDirect3DSurface9_Release(dst_surface);
12558 IDirect3DSurface9_Release(src_surface);
12561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12562 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12563 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12564 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12565 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12566 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12567 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12568 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12569 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12570 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12571 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12572 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12574 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12575 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12577 hr = IDirect3DDevice9_BeginScene(device);
12578 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12579 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12580 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12581 hr = IDirect3DDevice9_EndScene(device);
12582 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12584 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12586 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12587 ok(color_match(color, expected_colors[i].color, 0),
12588 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12589 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12592 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12593 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12595 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12596 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12597 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12598 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12599 IDirect3DTexture9_Release(dst_tex);
12600 IDirect3DTexture9_Release(src_tex);
12603 START_TEST(visual)
12605 IDirect3DDevice9 *device_ptr;
12606 D3DCAPS9 caps;
12607 HRESULT hr;
12608 DWORD color;
12610 d3d9_handle = LoadLibraryA("d3d9.dll");
12611 if (!d3d9_handle)
12613 skip("Could not load d3d9.dll\n");
12614 return;
12617 device_ptr = init_d3d9();
12618 if (!device_ptr)
12620 skip("Creating the device failed\n");
12621 return;
12624 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12626 /* Check for the reliability of the returned data */
12627 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12628 if(FAILED(hr))
12630 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12631 goto cleanup;
12634 color = getPixelColor(device_ptr, 1, 1);
12635 if(color !=0x00ff0000)
12637 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12638 goto cleanup;
12640 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12642 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12643 if(FAILED(hr))
12645 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12646 goto cleanup;
12649 color = getPixelColor(device_ptr, 639, 479);
12650 if(color != 0x0000ddee)
12652 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12653 goto cleanup;
12655 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12657 /* Now execute the real tests */
12658 depth_clamp_test(device_ptr);
12659 stretchrect_test(device_ptr);
12660 lighting_test(device_ptr);
12661 clear_test(device_ptr);
12662 color_fill_test(device_ptr);
12663 fog_test(device_ptr);
12664 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12666 test_cube_wrap(device_ptr);
12667 } else {
12668 skip("No cube texture support\n");
12670 z_range_test(device_ptr);
12671 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12673 maxmip_test(device_ptr);
12675 else
12677 skip("No mipmap support\n");
12679 offscreen_test(device_ptr);
12680 ds_size_test(device_ptr);
12681 alpha_test(device_ptr);
12682 shademode_test(device_ptr);
12683 srgbtexture_test(device_ptr);
12684 release_buffer_test(device_ptr);
12685 float_texture_test(device_ptr);
12686 g16r16_texture_test(device_ptr);
12687 pixelshader_blending_test(device_ptr);
12688 texture_transform_flags_test(device_ptr);
12689 autogen_mipmap_test(device_ptr);
12690 fixed_function_decl_test(device_ptr);
12691 conditional_np2_repeat_test(device_ptr);
12692 fixed_function_bumpmap_test(device_ptr);
12693 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12694 stencil_cull_test(device_ptr);
12695 } else {
12696 skip("No two sided stencil support\n");
12698 pointsize_test(device_ptr);
12699 tssargtemp_test(device_ptr);
12700 np2_stretch_rect_test(device_ptr);
12701 yuv_color_test(device_ptr);
12702 zwriteenable_test(device_ptr);
12703 alphatest_test(device_ptr);
12704 viewport_test(device_ptr);
12706 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12708 test_constant_clamp_vs(device_ptr);
12709 test_compare_instructions(device_ptr);
12711 else skip("No vs_1_1 support\n");
12713 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12715 test_mova(device_ptr);
12716 loop_index_test(device_ptr);
12717 sincos_test(device_ptr);
12718 sgn_test(device_ptr);
12719 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12720 test_vshader_input(device_ptr);
12721 test_vshader_float16(device_ptr);
12722 stream_test(device_ptr);
12723 } else {
12724 skip("No vs_3_0 support\n");
12727 else skip("No vs_2_0 support\n");
12729 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12731 fog_with_shader_test(device_ptr);
12733 else skip("No vs_1_1 and ps_1_1 support\n");
12735 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12737 texbem_test(device_ptr);
12738 texdepth_test(device_ptr);
12739 texkill_test(device_ptr);
12740 x8l8v8u8_test(device_ptr);
12741 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12742 constant_clamp_ps_test(device_ptr);
12743 cnd_test(device_ptr);
12744 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12745 dp2add_ps_test(device_ptr);
12746 unbound_sampler_test(device_ptr);
12747 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12748 nested_loop_test(device_ptr);
12749 pretransformed_varying_test(device_ptr);
12750 vFace_register_test(device_ptr);
12751 vpos_register_test(device_ptr);
12752 multiple_rendertargets_test(device_ptr);
12753 } else {
12754 skip("No ps_3_0 or vs_3_0 support\n");
12756 } else {
12757 skip("No ps_2_0 support\n");
12761 else skip("No ps_1_1 support\n");
12763 texop_test(device_ptr);
12764 texop_range_test(device_ptr);
12765 alphareplicate_test(device_ptr);
12766 dp3_alpha_test(device_ptr);
12767 depth_buffer_test(device_ptr);
12768 depth_buffer2_test(device_ptr);
12769 depth_blit_test(device_ptr);
12770 intz_test(device_ptr);
12771 shadow_test(device_ptr);
12772 fp_special_test(device_ptr);
12773 depth_bounds_test(device_ptr);
12774 srgbwrite_format_test(device_ptr);
12775 clip_planes_test(device_ptr);
12776 update_surface_test(device_ptr);
12778 cleanup:
12779 if(device_ptr) {
12780 D3DPRESENT_PARAMETERS present_parameters;
12781 IDirect3DSwapChain9 *swapchain;
12782 ULONG ref;
12784 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12785 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12786 IDirect3DSwapChain9_Release(swapchain);
12787 ref = IDirect3DDevice9_Release(device_ptr);
12788 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12789 DestroyWindow(present_parameters.hDeviceWindow);