d3d9/tests: Add a test for clip planes.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blob0800892bdd8dfe09de5928cf584de1bc4135d069
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, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
204 if(FAILED(hr)) {
205 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
206 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
207 if(FAILED(hr)) {
208 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
211 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
213 return device_ptr;
216 struct vertex
218 float x, y, z;
219 DWORD diffuse;
222 struct tvertex
224 float x, y, z, rhw;
225 DWORD diffuse;
228 struct nvertex
230 float x, y, z;
231 float nx, ny, nz;
232 DWORD diffuse;
235 static void lighting_test(IDirect3DDevice9 *device)
237 HRESULT hr;
238 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
239 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
240 DWORD color;
241 D3DMATERIAL9 material, old_material;
242 DWORD cop, carg;
244 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
245 0.0f, 1.0f, 0.0f, 0.0f,
246 0.0f, 0.0f, 1.0f, 0.0f,
247 0.0f, 0.0f, 0.0f, 1.0f };
249 struct vertex unlitquad[] =
251 {-1.0f, -1.0f, 0.1f, 0xffff0000},
252 {-1.0f, 0.0f, 0.1f, 0xffff0000},
253 { 0.0f, 0.0f, 0.1f, 0xffff0000},
254 { 0.0f, -1.0f, 0.1f, 0xffff0000},
256 struct vertex litquad[] =
258 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
259 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
260 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
261 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
263 struct nvertex unlitnquad[] =
265 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
267 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
268 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
270 struct nvertex litnquad[] =
272 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
274 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
275 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
277 WORD Indices[] = {0, 1, 2, 2, 3, 0};
279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
280 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
282 /* Setup some states that may cause issues */
283 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
286 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
287 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
288 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
290 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
296 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
306 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
308 hr = IDirect3DDevice9_SetFVF(device, 0);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
311 hr = IDirect3DDevice9_SetFVF(device, fvf);
312 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
314 hr = IDirect3DDevice9_BeginScene(device);
315 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
316 if(hr == D3D_OK)
318 /* No lights are defined... That means, lit vertices should be entirely black */
319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
320 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
321 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
322 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
323 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
326 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
327 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
328 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
329 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
331 hr = IDirect3DDevice9_SetFVF(device, nfvf);
332 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
336 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
337 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
338 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
342 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
343 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
344 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
346 IDirect3DDevice9_EndScene(device);
347 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
350 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
351 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
352 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
353 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
354 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
355 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
356 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
357 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
359 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
361 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
362 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
363 memset(&material, 0, sizeof(material));
364 material.Diffuse.r = 0.0;
365 material.Diffuse.g = 0.0;
366 material.Diffuse.b = 0.0;
367 material.Diffuse.a = 1.0;
368 material.Ambient.r = 0.0;
369 material.Ambient.g = 0.0;
370 material.Ambient.b = 0.0;
371 material.Ambient.a = 0.0;
372 material.Specular.r = 0.0;
373 material.Specular.g = 0.0;
374 material.Specular.b = 0.0;
375 material.Specular.a = 0.0;
376 material.Emissive.r = 0.0;
377 material.Emissive.g = 0.0;
378 material.Emissive.b = 0.0;
379 material.Emissive.a = 0.0;
380 material.Power = 0.0;
381 IDirect3DDevice9_SetMaterial(device, &material);
382 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
385 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
387 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
389 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
390 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
392 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
393 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
394 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
395 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
396 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
398 hr = IDirect3DDevice9_BeginScene(device);
399 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
400 if(SUCCEEDED(hr)) {
401 struct vertex lighting_test[] = {
402 {-1.0, -1.0, 0.1, 0x8000ff00},
403 { 1.0, -1.0, 0.1, 0x80000000},
404 {-1.0, 1.0, 0.1, 0x8000ff00},
405 { 1.0, 1.0, 0.1, 0x80000000}
407 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
408 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
410 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
412 hr = IDirect3DDevice9_EndScene(device);
413 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
416 color = getPixelColor(device, 320, 240);
417 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
418 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
421 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
423 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
425 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %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 unstransformed_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 unstransformed_2[] = {
888 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
889 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
890 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
891 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
893 /* Untransformed ones. Give them a different diffuse color to make the test look
894 * nicer. It also makes making sure that they are drawn correctly easier.
896 struct sVertexT transformed_1[] = {
897 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
898 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
899 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
900 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
902 struct sVertexT transformed_2[] = {
903 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
904 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
905 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
906 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
908 struct vertex rev_fog_quads[] = {
909 {-1.0, -1.0, 0.1, 0x000000ff},
910 {-1.0, 0.0, 0.1, 0x000000ff},
911 { 0.0, 0.0, 0.1, 0x000000ff},
912 { 0.0, -1.0, 0.1, 0x000000ff},
914 { 0.0, -1.0, 0.9, 0x000000ff},
915 { 0.0, 0.0, 0.9, 0x000000ff},
916 { 1.0, 0.0, 0.9, 0x000000ff},
917 { 1.0, -1.0, 0.9, 0x000000ff},
919 { 0.0, 0.0, 0.4, 0x000000ff},
920 { 0.0, 1.0, 0.4, 0x000000ff},
921 { 1.0, 1.0, 0.4, 0x000000ff},
922 { 1.0, 0.0, 0.4, 0x000000ff},
924 {-1.0, 0.0, 0.7, 0x000000ff},
925 {-1.0, 1.0, 0.7, 0x000000ff},
926 { 0.0, 1.0, 0.7, 0x000000ff},
927 { 0.0, 0.0, 0.7, 0x000000ff},
929 WORD Indices[] = {0, 1, 2, 2, 3, 0};
931 memset(&caps, 0, sizeof(caps));
932 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
933 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
934 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
935 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
937 /* Setup initial states: No lighting, fog on, fog color */
938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
939 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
941 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
943 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
945 /* First test: Both table fog and vertex fog off */
946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
949 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
951 /* Start = 0, end = 1. Should be default, but set them */
952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
953 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
955 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
957 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
960 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
961 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
962 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
964 sizeof(unstransformed_1[0]));
965 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
967 /* That makes it use the Z value */
968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
969 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
970 /* Untransformed, vertex fog != none (or table fog != none):
971 * Use the Z value as input into the equation
973 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
975 sizeof(unstransformed_1[0]));
976 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
978 /* transformed verts */
979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
980 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
981 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
982 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
983 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
984 sizeof(transformed_1[0]));
985 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
988 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
989 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
990 * equation
992 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
993 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
994 sizeof(transformed_2[0]));
995 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
997 hr = IDirect3DDevice9_EndScene(device);
998 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1000 else
1002 ok(FALSE, "BeginScene failed\n");
1005 color = getPixelColor(device, 160, 360);
1006 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1007 color = getPixelColor(device, 160, 120);
1008 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1009 color = getPixelColor(device, 480, 120);
1010 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1011 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1013 color = getPixelColor(device, 480, 360);
1014 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1016 else
1018 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1019 * The settings above result in no fogging with vertex fog
1021 color = getPixelColor(device, 480, 120);
1022 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1023 trace("Info: Table fog not supported by this device\n");
1025 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1027 /* Now test the special case fogstart == fogend */
1028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1029 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1031 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1033 start = 512;
1034 end = 512;
1035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1036 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1038 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1043 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1047 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1048 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1049 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1050 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1051 * color and has fixed fogstart and fogend.
1053 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1055 sizeof(unstransformed_1[0]));
1056 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1058 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1059 sizeof(unstransformed_1[0]));
1060 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1062 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1063 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1064 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1065 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1066 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1067 sizeof(transformed_1[0]));
1068 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1070 hr = IDirect3DDevice9_EndScene(device);
1071 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1073 else
1075 ok(FALSE, "BeginScene failed\n");
1077 color = getPixelColor(device, 160, 360);
1078 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1079 color = getPixelColor(device, 160, 120);
1080 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1081 color = getPixelColor(device, 480, 120);
1082 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1083 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1085 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1086 * but without shaders it seems to work everywhere
1088 end = 0.2;
1089 start = 0.8;
1090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1091 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1093 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1094 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1095 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1097 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1098 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1099 * so skip this for now
1101 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1102 const char *mode = (i ? "table" : "vertex");
1103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1104 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1106 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1108 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1109 hr = IDirect3DDevice9_BeginScene(device);
1110 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1111 if(SUCCEEDED(hr)) {
1112 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1113 4, 5, 6, 6, 7, 4,
1114 8, 9, 10, 10, 11, 8,
1115 12, 13, 14, 14, 15, 12};
1117 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1118 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1119 sizeof(rev_fog_quads[0]));
1120 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1122 hr = IDirect3DDevice9_EndScene(device);
1123 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1125 color = getPixelColor(device, 160, 360);
1126 ok(color_match(color, 0x0000ff00, 1),
1127 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1129 color = getPixelColor(device, 160, 120);
1130 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1131 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1133 color = getPixelColor(device, 480, 120);
1134 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1135 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1137 color = getPixelColor(device, 480, 360);
1138 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1140 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1142 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1143 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1144 break;
1147 /* Turn off the fog master switch to avoid confusing other tests */
1148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1149 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1150 start = 0.0;
1151 end = 1.0;
1152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1153 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1155 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1157 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1159 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1162 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1163 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1164 * regardless of the actual addressing mode set. The way this test works is
1165 * that we sample in one of the corners of the cubemap with filtering enabled,
1166 * and check the interpolated color. There are essentially two reasonable
1167 * things an implementation can do: Either pick one of the faces and
1168 * interpolate the edge texel with itself (i.e., clamp within the face), or
1169 * interpolate between the edge texels of the three involved faces. It should
1170 * never involve the border color or the other side (texcoord wrapping) of a
1171 * face in the interpolation. */
1172 static void test_cube_wrap(IDirect3DDevice9 *device)
1174 static const float quad[][6] = {
1175 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1176 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1177 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1178 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1181 static const D3DVERTEXELEMENT9 decl_elements[] = {
1182 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1183 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1184 D3DDECL_END()
1187 static const struct {
1188 D3DTEXTUREADDRESS mode;
1189 const char *name;
1190 } address_modes[] = {
1191 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1192 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1193 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1194 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1195 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1198 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1199 IDirect3DCubeTexture9 *texture = NULL;
1200 IDirect3DSurface9 *surface = NULL;
1201 IDirect3DSurface9 *face_surface;
1202 D3DLOCKED_RECT locked_rect;
1203 HRESULT hr;
1204 UINT x;
1205 INT y, face;
1207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1208 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1209 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1210 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1212 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1213 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1214 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1216 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1217 D3DPOOL_DEFAULT, &texture, NULL);
1218 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1220 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1221 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1223 for (y = 0; y < 128; ++y)
1225 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1226 for (x = 0; x < 64; ++x)
1228 *ptr++ = 0xff0000ff;
1230 for (x = 64; x < 128; ++x)
1232 *ptr++ = 0xffff0000;
1236 hr = IDirect3DSurface9_UnlockRect(surface);
1237 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1239 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1240 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1242 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1243 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1245 IDirect3DSurface9_Release(face_surface);
1247 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1248 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1250 for (y = 0; y < 128; ++y)
1252 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1253 for (x = 0; x < 64; ++x)
1255 *ptr++ = 0xffff0000;
1257 for (x = 64; x < 128; ++x)
1259 *ptr++ = 0xff0000ff;
1263 hr = IDirect3DSurface9_UnlockRect(surface);
1264 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1266 /* Create cube faces */
1267 for (face = 1; face < 6; ++face)
1269 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1270 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1272 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1273 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1275 IDirect3DSurface9_Release(face_surface);
1278 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1279 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1281 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1282 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1283 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1284 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1285 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1286 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1291 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1293 DWORD color;
1295 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1296 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1297 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1298 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1300 hr = IDirect3DDevice9_BeginScene(device);
1301 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1304 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1306 hr = IDirect3DDevice9_EndScene(device);
1307 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1309 color = getPixelColor(device, 320, 240);
1310 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1311 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1312 color, address_modes[x].name);
1314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1318 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1321 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1322 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1324 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1325 IDirect3DCubeTexture9_Release(texture);
1326 IDirect3DSurface9_Release(surface);
1329 static void offscreen_test(IDirect3DDevice9 *device)
1331 HRESULT hr;
1332 IDirect3DTexture9 *offscreenTexture = NULL;
1333 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1334 DWORD color;
1336 static const float quad[][5] = {
1337 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1338 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1339 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1340 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1344 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1346 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1347 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1348 if(!offscreenTexture) {
1349 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1350 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1351 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1352 if(!offscreenTexture) {
1353 skip("Cannot create an offscreen render target\n");
1354 goto out;
1358 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1359 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1360 if(!backbuffer) {
1361 goto out;
1364 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1365 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1366 if(!offscreen) {
1367 goto out;
1370 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1371 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1373 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1374 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1375 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1376 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1377 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1378 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1379 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1380 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1382 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1384 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1385 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1386 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1388 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1390 /* Draw without textures - Should result in a white quad */
1391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1392 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1394 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1395 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1396 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1397 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1399 /* This time with the texture */
1400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1401 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1403 IDirect3DDevice9_EndScene(device);
1406 /* Center quad - should be white */
1407 color = getPixelColor(device, 320, 240);
1408 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1409 /* Some quad in the cleared part of the texture */
1410 color = getPixelColor(device, 170, 240);
1411 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1412 /* Part of the originally cleared back buffer */
1413 color = getPixelColor(device, 10, 10);
1414 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1415 if(0) {
1416 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1417 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1418 * the offscreen rendering mode this test would succeed or fail
1420 color = getPixelColor(device, 10, 470);
1421 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1424 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1426 out:
1427 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1430 /* restore things */
1431 if(backbuffer) {
1432 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1433 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1434 IDirect3DSurface9_Release(backbuffer);
1436 if(offscreenTexture) {
1437 IDirect3DTexture9_Release(offscreenTexture);
1439 if(offscreen) {
1440 IDirect3DSurface9_Release(offscreen);
1444 /* This test tests fog in combination with shaders.
1445 * What's tested: linear fog (vertex and table) with pixel shader
1446 * linear table fog with non foggy vertex shader
1447 * vertex fog with foggy vertex shader, non-linear
1448 * fog with shader, non-linear fog with foggy shader,
1449 * linear table fog with foggy shader
1451 static void fog_with_shader_test(IDirect3DDevice9 *device)
1453 HRESULT hr;
1454 DWORD color;
1455 union {
1456 float f;
1457 DWORD i;
1458 } start, end;
1459 unsigned int i, j;
1461 /* basic vertex shader without fog computation ("non foggy") */
1462 static const DWORD vertex_shader_code1[] = {
1463 0xfffe0101, /* vs_1_1 */
1464 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1465 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1466 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1467 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1468 0x0000ffff
1470 /* basic vertex shader with reversed fog computation ("foggy") */
1471 static const DWORD vertex_shader_code2[] = {
1472 0xfffe0101, /* vs_1_1 */
1473 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1474 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1475 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1476 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1477 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1478 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1479 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1480 0x0000ffff
1482 /* basic pixel shader */
1483 static const DWORD pixel_shader_code[] = {
1484 0xffff0101, /* ps_1_1 */
1485 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1486 0x0000ffff
1489 static struct vertex quad[] = {
1490 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1491 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1492 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1493 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1496 static const D3DVERTEXELEMENT9 decl_elements[] = {
1497 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1498 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1499 D3DDECL_END()
1502 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1503 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1504 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1506 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1507 static const struct test_data_t {
1508 int vshader;
1509 int pshader;
1510 D3DFOGMODE vfog;
1511 D3DFOGMODE tfog;
1512 unsigned int color[11];
1513 } test_data[] = {
1514 /* only pixel shader: */
1515 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1516 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1517 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1518 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1519 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1520 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1521 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1522 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1523 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1525 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1531 /* vertex shader */
1532 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1533 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1534 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1535 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1536 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1537 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1538 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1539 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1540 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1542 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1543 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1544 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1545 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1546 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1547 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1549 /* vertex shader and pixel shader */
1550 /* The next 4 tests would read the fog coord output, but it isn't available.
1551 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1552 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1553 * These tests should be disabled if some other hardware behaves differently
1555 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1556 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1557 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1558 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1559 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1560 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1561 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1562 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1563 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1564 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1565 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1566 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1568 /* These use the Z coordinate with linear table fog */
1569 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1570 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1571 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1572 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1573 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1574 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1575 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1576 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1577 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1578 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1579 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1580 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1582 /* Non-linear table fog without fog coord */
1583 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1584 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1585 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1586 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1587 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1588 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1590 #if 0 /* FIXME: these fail on GeForce 8500 */
1591 /* foggy vertex shader */
1592 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1593 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1594 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1595 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1596 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1597 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1598 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1599 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1600 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1601 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1602 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1603 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 #endif
1606 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1607 * all using the fixed fog-coord linear fog
1609 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1610 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1611 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1612 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1613 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1614 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1615 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1616 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1617 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1618 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1619 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1620 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1622 /* These use table fog. Here the shader-provided fog coordinate is
1623 * ignored and the z coordinate used instead
1625 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1626 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1627 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1628 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1629 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1630 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1631 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1632 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1633 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1636 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1637 start.f=0.1f;
1638 end.f=0.9f;
1640 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1641 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1642 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1643 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1644 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1645 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1646 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1647 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1649 /* Setup initial states: No lighting, fog on, fog color */
1650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1651 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1653 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1655 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1656 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1657 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1660 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1662 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1664 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1666 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1668 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1670 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1672 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1673 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1674 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1675 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1677 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1679 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1681 for(j=0; j < 11; j++)
1683 /* Don't use the whole zrange to prevent rounding errors */
1684 quad[0].z = 0.001f + (float)j / 10.02f;
1685 quad[1].z = 0.001f + (float)j / 10.02f;
1686 quad[2].z = 0.001f + (float)j / 10.02f;
1687 quad[3].z = 0.001f + (float)j / 10.02f;
1689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1690 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1692 hr = IDirect3DDevice9_BeginScene(device);
1693 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1696 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1698 hr = IDirect3DDevice9_EndScene(device);
1699 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1701 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1702 color = getPixelColor(device, 128, 240);
1703 ok(color_match(color, test_data[i].color[j], 13),
1704 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1705 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1707 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1711 /* reset states */
1712 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1713 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1714 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1715 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1716 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1717 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1719 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1721 IDirect3DVertexShader9_Release(vertex_shader[1]);
1722 IDirect3DVertexShader9_Release(vertex_shader[2]);
1723 IDirect3DPixelShader9_Release(pixel_shader[1]);
1724 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1727 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1728 unsigned int i, x, y;
1729 HRESULT hr;
1730 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1731 D3DLOCKED_RECT locked_rect;
1733 /* Generate the textures */
1734 for(i=0; i<2; i++)
1736 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1737 D3DPOOL_MANAGED, &texture[i], NULL);
1738 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1740 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1741 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742 for (y = 0; y < 128; ++y)
1744 if(i)
1745 { /* Set up black texture with 2x2 texel white spot in the middle */
1746 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1747 for (x = 0; x < 128; ++x)
1749 if(y>62 && y<66 && x>62 && x<66)
1750 *ptr++ = 0xffffffff;
1751 else
1752 *ptr++ = 0xff000000;
1755 else
1756 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1757 * (if multiplied with bumpenvmat)
1759 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1760 for (x = 0; x < 128; ++x)
1762 if(abs(x-64)>abs(y-64))
1764 if(x < 64)
1765 *ptr++ = 0xc000;
1766 else
1767 *ptr++ = 0x4000;
1769 else
1771 if(y < 64)
1772 *ptr++ = 0x0040;
1773 else
1774 *ptr++ = 0x00c0;
1779 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1780 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1782 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1783 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1785 /* Disable texture filtering */
1786 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1787 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1788 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1789 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1791 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1792 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1793 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1794 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1798 /* test the behavior of the texbem instruction
1799 * with normal 2D and projective 2D textures
1801 static void texbem_test(IDirect3DDevice9 *device)
1803 HRESULT hr;
1804 DWORD color;
1805 int i;
1807 static const DWORD pixel_shader_code[] = {
1808 0xffff0101, /* ps_1_1*/
1809 0x00000042, 0xb00f0000, /* tex t0*/
1810 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1811 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1812 0x0000ffff
1814 static const DWORD double_texbem_code[] = {
1815 0xffff0103, /* ps_1_3 */
1816 0x00000042, 0xb00f0000, /* tex t0 */
1817 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1818 0x00000042, 0xb00f0002, /* tex t2 */
1819 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1820 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1821 0x0000ffff /* end */
1825 static const float quad[][7] = {
1826 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1827 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1828 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1829 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1831 static const float quad_proj[][9] = {
1832 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1833 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1834 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1835 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1838 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1839 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842 D3DDECL_END()
1844 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1845 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1846 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1847 D3DDECL_END()
1848 } };
1850 /* use asymmetric matrix to test loading */
1851 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1853 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1854 IDirect3DPixelShader9 *pixel_shader = NULL;
1855 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1856 D3DLOCKED_RECT locked_rect;
1858 generate_bumpmap_textures(device);
1860 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1861 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1862 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1863 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1864 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1866 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1867 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1869 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1872 for(i=0; i<2; i++)
1874 if(i)
1876 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1877 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1880 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1881 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1882 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1883 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1885 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1886 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1887 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1888 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1890 hr = IDirect3DDevice9_BeginScene(device);
1891 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1893 if(!i)
1894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1895 else
1896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1897 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1899 hr = IDirect3DDevice9_EndScene(device);
1900 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1902 color = getPixelColor(device, 320-32, 240);
1903 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1904 color = getPixelColor(device, 320+32, 240);
1905 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906 color = getPixelColor(device, 320, 240-32);
1907 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1908 color = getPixelColor(device, 320, 240+32);
1909 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1911 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1912 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1914 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1915 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1916 IDirect3DPixelShader9_Release(pixel_shader);
1918 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1919 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1920 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1923 /* clean up */
1924 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1925 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1928 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1930 for(i=0; i<2; i++)
1932 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1933 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1934 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1935 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1936 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1937 IDirect3DTexture9_Release(texture);
1940 /* Test double texbem */
1941 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1942 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1943 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1944 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1945 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1946 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1947 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1948 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1950 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1951 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1952 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1953 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1955 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1956 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1958 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1959 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1960 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1961 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1962 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1963 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1966 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1967 #define tex 0x00ff0000
1968 #define tex1 0x0000ff00
1969 #define origin 0x000000ff
1970 static const DWORD pixel_data[] = {
1971 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1974 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1975 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1976 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1977 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1978 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1980 #undef tex1
1981 #undef tex2
1982 #undef origin
1984 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1985 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1986 for(i = 0; i < 8; i++) {
1987 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1989 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1990 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1993 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1994 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1995 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1996 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1997 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1998 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1999 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2000 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2001 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2002 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2004 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2006 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2007 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2008 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2009 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2011 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2012 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2013 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2014 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2017 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2018 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2019 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2020 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2021 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2022 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2023 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2025 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2026 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2028 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2029 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2030 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2031 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2032 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2033 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2034 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2035 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2036 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2037 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2038 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2039 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2040 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2042 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2043 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2045 hr = IDirect3DDevice9_BeginScene(device);
2046 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2047 if(SUCCEEDED(hr)) {
2048 static const float double_quad[] = {
2049 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2050 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2051 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2052 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2056 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2057 hr = IDirect3DDevice9_EndScene(device);
2058 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2060 color = getPixelColor(device, 320, 240);
2061 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2063 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2065 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2067 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2069 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2070 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2071 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2072 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2075 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2077 IDirect3DPixelShader9_Release(pixel_shader);
2078 IDirect3DTexture9_Release(texture);
2079 IDirect3DTexture9_Release(texture1);
2080 IDirect3DTexture9_Release(texture2);
2083 static void z_range_test(IDirect3DDevice9 *device)
2085 const struct vertex quad[] =
2087 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2088 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2089 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2090 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2092 const struct vertex quad2[] =
2094 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2095 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2096 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2097 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2100 const struct tvertex quad3[] =
2102 { 0, 240, 1.1f, 1.0, 0xffffff00},
2103 { 0, 480, 1.1f, 1.0, 0xffffff00},
2104 { 640, 240, -1.1f, 1.0, 0xffffff00},
2105 { 640, 480, -1.1f, 1.0, 0xffffff00},
2107 const struct tvertex quad4[] =
2109 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2110 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2111 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2112 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2114 HRESULT hr;
2115 DWORD color;
2116 IDirect3DVertexShader9 *shader;
2117 IDirect3DVertexDeclaration9 *decl;
2118 D3DCAPS9 caps;
2119 const DWORD shader_code[] = {
2120 0xfffe0101, /* vs_1_1 */
2121 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2122 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2123 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2124 0x0000ffff /* end */
2126 static const D3DVERTEXELEMENT9 decl_elements[] = {
2127 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2128 D3DDECL_END()
2130 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2131 * then call Present. Then clear the color buffer to make sure it has some defined content
2132 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2133 * by the depth value.
2135 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2136 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2138 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2140 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2147 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2149 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2151 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2153 hr = IDirect3DDevice9_BeginScene(device);
2154 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2155 if(hr == D3D_OK)
2157 /* Test the untransformed vertex path */
2158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2159 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2161 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2163 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2165 /* Test the transformed vertex path */
2166 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2167 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2169 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2170 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2174 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2176 hr = IDirect3DDevice9_EndScene(device);
2177 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2180 /* Do not test the exact corner pixels, but go pretty close to them */
2182 /* Clipped because z > 1.0 */
2183 color = getPixelColor(device, 28, 238);
2184 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2185 color = getPixelColor(device, 28, 241);
2186 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2188 /* Not clipped, > z buffer clear value(0.75) */
2189 color = getPixelColor(device, 31, 238);
2190 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2191 color = getPixelColor(device, 31, 241);
2192 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2193 color = getPixelColor(device, 100, 238);
2194 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2195 color = getPixelColor(device, 100, 241);
2196 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2198 /* Not clipped, < z buffer clear value */
2199 color = getPixelColor(device, 104, 238);
2200 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2201 color = getPixelColor(device, 104, 241);
2202 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2203 color = getPixelColor(device, 318, 238);
2204 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2205 color = getPixelColor(device, 318, 241);
2206 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2208 /* Clipped because z < 0.0 */
2209 color = getPixelColor(device, 321, 238);
2210 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2211 color = getPixelColor(device, 321, 241);
2212 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2214 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2215 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2217 /* Test the shader path */
2218 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2219 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2220 skip("Vertex shaders not supported\n");
2221 goto out;
2223 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2225 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2226 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2228 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2230 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2232 IDirect3DDevice9_SetVertexShader(device, shader);
2233 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2235 hr = IDirect3DDevice9_BeginScene(device);
2236 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2237 if(hr == D3D_OK)
2239 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2240 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2241 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2243 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2245 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2246 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2248 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2250 hr = IDirect3DDevice9_EndScene(device);
2251 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2254 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2255 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2256 IDirect3DDevice9_SetVertexShader(device, NULL);
2257 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2259 IDirect3DVertexDeclaration9_Release(decl);
2260 IDirect3DVertexShader9_Release(shader);
2262 /* Z < 1.0 */
2263 color = getPixelColor(device, 28, 238);
2264 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2266 /* 1.0 < z < 0.75 */
2267 color = getPixelColor(device, 31, 238);
2268 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2269 color = getPixelColor(device, 100, 238);
2270 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2272 /* 0.75 < z < 0.0 */
2273 color = getPixelColor(device, 104, 238);
2274 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2275 color = getPixelColor(device, 318, 238);
2276 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2278 /* 0.0 < z */
2279 color = getPixelColor(device, 321, 238);
2280 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2282 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2283 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2285 out:
2286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2294 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2296 D3DSURFACE_DESC desc;
2297 D3DLOCKED_RECT l;
2298 HRESULT hr;
2299 unsigned int x, y;
2300 DWORD *mem;
2302 memset(&desc, 0, sizeof(desc));
2303 memset(&l, 0, sizeof(l));
2304 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2305 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2306 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2307 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2308 if(FAILED(hr)) return;
2310 for(y = 0; y < desc.Height; y++)
2312 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2313 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2315 mem[x] = color;
2318 hr = IDirect3DSurface9_UnlockRect(surface);
2319 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2322 /* This tests a variety of possible StretchRect() situations */
2323 static void stretchrect_test(IDirect3DDevice9 *device)
2325 HRESULT hr;
2326 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2327 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2328 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2329 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2330 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2331 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2332 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2333 IDirect3DSurface9 *orig_rt = NULL;
2334 IDirect3DSurface9 *backbuffer = NULL;
2335 DWORD color;
2337 RECT src_rect64 = {0, 0, 64, 64};
2338 RECT src_rect64_flipy = {0, 64, 64, 0};
2339 RECT dst_rect64 = {0, 0, 64, 64};
2340 RECT dst_rect64_flipy = {0, 64, 64, 0};
2342 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2343 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2344 if(!orig_rt) {
2345 goto out;
2348 /* Create our temporary surfaces in system memory */
2349 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2350 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2351 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2352 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2354 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2355 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2356 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2357 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2358 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2359 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2360 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2362 /* Create render target surfaces */
2363 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2364 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2365 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2366 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2367 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2368 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2369 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2370 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2372 /* Create render target textures */
2373 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2374 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2375 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2376 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2377 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2378 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2379 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2380 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2381 if (tex_rt32) {
2382 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2383 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2385 if (tex_rt64) {
2386 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2387 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2389 if (tex_rt_dest64) {
2390 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2391 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2393 if (tex_rt_dest64) {
2394 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2395 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398 /* Create regular textures in D3DPOOL_DEFAULT */
2399 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2400 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2401 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2402 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2403 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2404 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2405 if (tex32) {
2406 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2407 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2409 if (tex64) {
2410 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2411 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2413 if (tex_dest64) {
2414 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2415 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2418 /*********************************************************************
2419 * Tests for when the source parameter is an offscreen plain surface *
2420 *********************************************************************/
2422 /* Fill the offscreen 64x64 surface with green */
2423 if (surf_offscreen64)
2424 fill_surface(surf_offscreen64, 0xff00ff00);
2426 /* offscreenplain ==> offscreenplain, same size */
2427 if(surf_offscreen64 && surf_offscreen_dest64) {
2428 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2429 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2431 if (hr == D3D_OK) {
2432 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2433 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2436 /* Blit without scaling */
2437 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2438 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2440 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2441 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2442 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2444 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2445 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2446 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2449 /* offscreenplain ==> rendertarget texture, same size */
2450 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2451 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2452 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454 /* We can't lock rendertarget textures, so copy to our temp surface first */
2455 if (hr == D3D_OK) {
2456 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2457 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2460 if (hr == D3D_OK) {
2461 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2462 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2465 /* Blit without scaling */
2466 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2467 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2469 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2470 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2471 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2474 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2475 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2478 /* offscreenplain ==> rendertarget surface, same size */
2479 if(surf_offscreen64 && surf_rt_dest64) {
2480 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2481 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2483 if (hr == D3D_OK) {
2484 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2485 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2488 /* Blit without scaling */
2489 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2490 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2492 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2493 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2494 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2496 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2497 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2498 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2501 /* offscreenplain ==> texture, same size (should fail) */
2502 if(surf_offscreen64 && surf_tex_dest64) {
2503 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2504 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2507 /* Fill the smaller offscreen surface with red */
2508 fill_surface(surf_offscreen32, 0xffff0000);
2510 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2511 if(surf_offscreen32 && surf_offscreen64) {
2512 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2513 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2516 /* offscreenplain ==> rendertarget texture, scaling */
2517 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2518 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2519 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2521 /* We can't lock rendertarget textures, so copy to our temp surface first */
2522 if (hr == D3D_OK) {
2523 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2524 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2527 if (hr == D3D_OK) {
2528 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2529 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2533 /* offscreenplain ==> rendertarget surface, scaling */
2534 if(surf_offscreen32 && surf_rt_dest64) {
2535 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2536 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2538 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2539 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2542 /* offscreenplain ==> texture, scaling (should fail) */
2543 if(surf_offscreen32 && surf_tex_dest64) {
2544 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2545 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2548 /************************************************************
2549 * Tests for when the source parameter is a regular texture *
2550 ************************************************************/
2552 /* Fill the surface of the regular texture with blue */
2553 if (surf_tex64 && surf_temp64) {
2554 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2555 fill_surface(surf_temp64, 0xff0000ff);
2556 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2557 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2560 /* texture ==> offscreenplain, same size */
2561 if(surf_tex64 && surf_offscreen64) {
2562 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2563 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2566 /* texture ==> rendertarget texture, same size */
2567 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2568 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2569 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571 /* We can't lock rendertarget textures, so copy to our temp surface first */
2572 if (hr == D3D_OK) {
2573 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2574 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2577 if (hr == D3D_OK) {
2578 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2579 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2582 /* Blit without scaling */
2583 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2584 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2586 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2587 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2588 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2591 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2592 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2595 /* texture ==> rendertarget surface, same size */
2596 if(surf_tex64 && surf_rt_dest64) {
2597 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2598 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2600 if (hr == D3D_OK) {
2601 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2602 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2605 /* Blit without scaling */
2606 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2607 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2609 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2610 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2611 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2613 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2614 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2615 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2618 /* texture ==> texture, same size (should fail) */
2619 if(surf_tex64 && surf_tex_dest64) {
2620 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2621 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2624 /* Fill the surface of the smaller regular texture with red */
2625 if (surf_tex32 && surf_temp32) {
2626 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2627 fill_surface(surf_temp32, 0xffff0000);
2628 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2629 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2632 /* texture ==> offscreenplain, scaling (should fail) */
2633 if(surf_tex32 && surf_offscreen64) {
2634 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2635 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2638 /* texture ==> rendertarget texture, scaling */
2639 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2640 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2641 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2643 /* We can't lock rendertarget textures, so copy to our temp surface first */
2644 if (hr == D3D_OK) {
2645 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2646 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2649 if (hr == D3D_OK) {
2650 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2651 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2655 /* texture ==> rendertarget surface, scaling */
2656 if(surf_tex32 && surf_rt_dest64) {
2657 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2658 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2660 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2661 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2664 /* texture ==> texture, scaling (should fail) */
2665 if(surf_tex32 && surf_tex_dest64) {
2666 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2667 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2670 /*****************************************************************
2671 * Tests for when the source parameter is a rendertarget texture *
2672 *****************************************************************/
2674 /* Fill the surface of the rendertarget texture with white */
2675 if (surf_tex_rt64 && surf_temp64) {
2676 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2677 fill_surface(surf_temp64, 0xffffffff);
2678 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2679 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2682 /* rendertarget texture ==> offscreenplain, same size */
2683 if(surf_tex_rt64 && surf_offscreen64) {
2684 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2685 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2688 /* rendertarget texture ==> rendertarget texture, same size */
2689 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2690 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2691 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693 /* We can't lock rendertarget textures, so copy to our temp surface first */
2694 if (hr == D3D_OK) {
2695 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2696 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2699 if (hr == D3D_OK) {
2700 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2701 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2704 /* Blit without scaling */
2705 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2706 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2708 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2709 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2710 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2713 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2714 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2717 /* rendertarget texture ==> rendertarget surface, same size */
2718 if(surf_tex_rt64 && surf_rt_dest64) {
2719 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2720 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2722 if (hr == D3D_OK) {
2723 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2724 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2727 /* Blit without scaling */
2728 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2729 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2731 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2732 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2733 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2735 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2736 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2737 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2740 /* rendertarget texture ==> texture, same size (should fail) */
2741 if(surf_tex_rt64 && surf_tex_dest64) {
2742 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2743 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2746 /* Fill the surface of the smaller rendertarget texture with red */
2747 if (surf_tex_rt32 && surf_temp32) {
2748 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2749 fill_surface(surf_temp32, 0xffff0000);
2750 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2751 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2754 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2755 if(surf_tex_rt32 && surf_offscreen64) {
2756 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2757 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2760 /* rendertarget texture ==> rendertarget texture, scaling */
2761 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2762 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2763 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2765 /* We can't lock rendertarget textures, so copy to our temp surface first */
2766 if (hr == D3D_OK) {
2767 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2768 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2771 if (hr == D3D_OK) {
2772 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2773 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2777 /* rendertarget texture ==> rendertarget surface, scaling */
2778 if(surf_tex_rt32 && surf_rt_dest64) {
2779 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2780 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2782 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2783 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2786 /* rendertarget texture ==> texture, scaling (should fail) */
2787 if(surf_tex_rt32 && surf_tex_dest64) {
2788 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2789 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2792 /*****************************************************************
2793 * Tests for when the source parameter is a rendertarget surface *
2794 *****************************************************************/
2796 /* Fill the surface of the rendertarget surface with black */
2797 if (surf_rt64)
2798 fill_surface(surf_rt64, 0xff000000);
2800 /* rendertarget texture ==> offscreenplain, same size */
2801 if(surf_rt64 && surf_offscreen64) {
2802 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2803 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2806 /* rendertarget surface ==> rendertarget texture, same size */
2807 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2808 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2809 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811 /* We can't lock rendertarget textures, so copy to our temp surface first */
2812 if (hr == D3D_OK) {
2813 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2814 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2817 if (hr == D3D_OK) {
2818 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2819 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2822 /* Blit without scaling */
2823 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2824 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2826 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2827 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2828 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2831 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2832 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835 /* rendertarget surface ==> rendertarget surface, same size */
2836 if(surf_rt64 && surf_rt_dest64) {
2837 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2838 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2840 if (hr == D3D_OK) {
2841 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2842 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2845 /* Blit without scaling */
2846 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2847 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2849 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2850 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2851 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2853 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2854 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2855 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2858 /* rendertarget surface ==> texture, same size (should fail) */
2859 if(surf_rt64 && surf_tex_dest64) {
2860 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2861 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2864 /* Fill the surface of the smaller rendertarget texture with red */
2865 if (surf_rt32)
2866 fill_surface(surf_rt32, 0xffff0000);
2868 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2869 if(surf_rt32 && surf_offscreen64) {
2870 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2871 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2874 /* rendertarget surface ==> rendertarget texture, scaling */
2875 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2876 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2877 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2879 /* We can't lock rendertarget textures, so copy to our temp surface first */
2880 if (hr == D3D_OK) {
2881 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2882 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2885 if (hr == D3D_OK) {
2886 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2887 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2891 /* rendertarget surface ==> rendertarget surface, scaling */
2892 if(surf_rt32 && surf_rt_dest64) {
2893 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2894 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2896 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2897 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2900 /* rendertarget surface ==> texture, scaling (should fail) */
2901 if(surf_rt32 && surf_tex_dest64) {
2902 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2903 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2906 /* backbuffer ==> surface tests (no scaling) */
2907 if(backbuffer && surf_tex_rt_dest640_480)
2909 RECT src_rect = {0, 0, 640, 480};
2910 RECT src_rect_flipy = {0, 480, 640, 0};
2911 RECT dst_rect = {0, 0, 640, 480};
2912 RECT dst_rect_flipy = {0, 480, 640, 0};
2914 /* Blit with NULL rectangles */
2915 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2916 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2918 /* Blit without scaling */
2919 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2920 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2922 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2923 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2924 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2926 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2927 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2928 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2931 /* TODO: Test format conversions */
2934 out:
2935 /* Clean up */
2936 if (backbuffer)
2937 IDirect3DSurface9_Release(backbuffer);
2938 if (surf_rt32)
2939 IDirect3DSurface9_Release(surf_rt32);
2940 if (surf_rt64)
2941 IDirect3DSurface9_Release(surf_rt64);
2942 if (surf_rt_dest64)
2943 IDirect3DSurface9_Release(surf_rt_dest64);
2944 if (surf_temp32)
2945 IDirect3DSurface9_Release(surf_temp32);
2946 if (surf_temp64)
2947 IDirect3DSurface9_Release(surf_temp64);
2948 if (surf_offscreen32)
2949 IDirect3DSurface9_Release(surf_offscreen32);
2950 if (surf_offscreen64)
2951 IDirect3DSurface9_Release(surf_offscreen64);
2952 if (surf_offscreen_dest64)
2953 IDirect3DSurface9_Release(surf_offscreen_dest64);
2955 if (tex_rt32) {
2956 if (surf_tex_rt32)
2957 IDirect3DSurface9_Release(surf_tex_rt32);
2958 IDirect3DTexture9_Release(tex_rt32);
2960 if (tex_rt64) {
2961 if (surf_tex_rt64)
2962 IDirect3DSurface9_Release(surf_tex_rt64);
2963 IDirect3DTexture9_Release(tex_rt64);
2965 if (tex_rt_dest64) {
2966 if (surf_tex_rt_dest64)
2967 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2968 IDirect3DTexture9_Release(tex_rt_dest64);
2970 if (tex_rt_dest640_480) {
2971 if (surf_tex_rt_dest640_480)
2972 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2973 IDirect3DTexture9_Release(tex_rt_dest640_480);
2975 if (tex32) {
2976 if (surf_tex32)
2977 IDirect3DSurface9_Release(surf_tex32);
2978 IDirect3DTexture9_Release(tex32);
2980 if (tex64) {
2981 if (surf_tex64)
2982 IDirect3DSurface9_Release(surf_tex64);
2983 IDirect3DTexture9_Release(tex64);
2985 if (tex_dest64) {
2986 if (surf_tex_dest64)
2987 IDirect3DSurface9_Release(surf_tex_dest64);
2988 IDirect3DTexture9_Release(tex_dest64);
2991 if (orig_rt) {
2992 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2993 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2994 IDirect3DSurface9_Release(orig_rt);
2998 static void maxmip_test(IDirect3DDevice9 *device)
3000 IDirect3DTexture9 *texture = NULL;
3001 IDirect3DSurface9 *surface = NULL;
3002 HRESULT hr;
3003 DWORD color;
3004 static const struct
3006 struct
3008 float x, y, z;
3009 float s, t;
3011 v[4];
3013 quads[] =
3016 {-1.0, -1.0, 0.0, 0.0, 0.0},
3017 {-1.0, 0.0, 0.0, 0.0, 1.0},
3018 { 0.0, -1.0, 0.0, 1.0, 0.0},
3019 { 0.0, 0.0, 0.0, 1.0, 1.0},
3022 { 0.0, -1.0, 0.0, 0.0, 0.0},
3023 { 0.0, 0.0, 0.0, 0.0, 1.0},
3024 { 1.0, -1.0, 0.0, 1.0, 0.0},
3025 { 1.0, 0.0, 0.0, 1.0, 1.0},
3028 { 0.0, 0.0, 0.0, 0.0, 0.0},
3029 { 0.0, 1.0, 0.0, 0.0, 1.0},
3030 { 1.0, 0.0, 0.0, 1.0, 0.0},
3031 { 1.0, 1.0, 0.0, 1.0, 1.0},
3034 {-1.0, 0.0, 0.0, 0.0, 0.0},
3035 {-1.0, 1.0, 0.0, 0.0, 1.0},
3036 { 0.0, 0.0, 0.0, 1.0, 0.0},
3037 { 0.0, 1.0, 0.0, 1.0, 1.0},
3041 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3042 &texture, NULL);
3043 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3044 if(!texture)
3046 skip("Failed to create test texture\n");
3047 return;
3050 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3051 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3052 fill_surface(surface, 0xffff0000);
3053 IDirect3DSurface9_Release(surface);
3054 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3055 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3056 fill_surface(surface, 0xff00ff00);
3057 IDirect3DSurface9_Release(surface);
3058 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3059 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3060 fill_surface(surface, 0xff0000ff);
3061 IDirect3DSurface9_Release(surface);
3063 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3064 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3065 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3066 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3068 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3069 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3071 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3072 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3074 hr = IDirect3DDevice9_BeginScene(device);
3075 if(SUCCEEDED(hr))
3077 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3078 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3080 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3082 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3083 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3085 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3087 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3088 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3089 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3090 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3093 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3094 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3095 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3096 hr = IDirect3DDevice9_EndScene(device);
3097 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3100 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3101 color = getPixelColor(device, 160, 360);
3102 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3103 color = getPixelColor(device, 480, 360);
3104 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3105 color = getPixelColor(device, 480, 120);
3106 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3107 color = getPixelColor(device, 160, 120);
3108 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3109 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3110 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3112 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3113 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3115 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3116 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3118 hr = IDirect3DDevice9_BeginScene(device);
3119 if(SUCCEEDED(hr))
3121 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3122 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3124 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3126 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3127 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3129 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3131 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3134 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3136 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3137 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3138 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3139 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3140 hr = IDirect3DDevice9_EndScene(device);
3141 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3144 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3145 * level 3 (> levels in texture) samples from the highest level in the
3146 * texture (level 2). */
3147 color = getPixelColor(device, 160, 360);
3148 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3149 color = getPixelColor(device, 480, 360);
3150 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3151 color = getPixelColor(device, 480, 120);
3152 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3153 color = getPixelColor(device, 160, 120);
3154 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3156 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3158 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3159 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3161 hr = IDirect3DDevice9_BeginScene(device);
3162 if(SUCCEEDED(hr))
3164 DWORD ret;
3166 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3168 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3169 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3170 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3171 ret = IDirect3DTexture9_SetLOD(texture, 1);
3172 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3174 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3176 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3177 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3178 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3179 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3180 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3181 ret = IDirect3DTexture9_SetLOD(texture, 2);
3182 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3184 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3186 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3187 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3188 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3189 ret = IDirect3DTexture9_SetLOD(texture, 1);
3190 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3191 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3192 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3194 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3195 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3196 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3197 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3198 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3199 ret = IDirect3DTexture9_SetLOD(texture, 1);
3200 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3201 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3202 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3203 hr = IDirect3DDevice9_EndScene(device);
3204 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3207 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3208 * level 3 (> levels in texture) samples from the highest level in the
3209 * texture (level 2). */
3210 color = getPixelColor(device, 160, 360);
3211 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3212 color = getPixelColor(device, 480, 360);
3213 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3214 color = getPixelColor(device, 480, 120);
3215 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3216 color = getPixelColor(device, 160, 120);
3217 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3219 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3220 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3222 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3223 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3224 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3225 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3226 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3227 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3228 IDirect3DTexture9_Release(texture);
3231 static void release_buffer_test(IDirect3DDevice9 *device)
3233 IDirect3DVertexBuffer9 *vb = NULL;
3234 IDirect3DIndexBuffer9 *ib = NULL;
3235 HRESULT hr;
3236 BYTE *data;
3237 LONG ref;
3239 static const struct vertex quad[] = {
3240 {-1.0, -1.0, 0.1, 0xffff0000},
3241 {-1.0, 1.0, 0.1, 0xffff0000},
3242 { 1.0, 1.0, 0.1, 0xffff0000},
3244 {-1.0, -1.0, 0.1, 0xff00ff00},
3245 {-1.0, 1.0, 0.1, 0xff00ff00},
3246 { 1.0, 1.0, 0.1, 0xff00ff00}
3248 short indices[] = {3, 4, 5};
3250 /* Index and vertex buffers should always be creatable */
3251 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3252 D3DPOOL_MANAGED, &vb, NULL);
3253 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3254 if(!vb) {
3255 skip("Failed to create a vertex buffer\n");
3256 return;
3258 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3259 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3260 if(!ib) {
3261 skip("Failed to create an index buffer\n");
3262 return;
3265 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3266 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3267 memcpy(data, quad, sizeof(quad));
3268 hr = IDirect3DVertexBuffer9_Unlock(vb);
3269 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3271 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3272 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3273 memcpy(data, indices, sizeof(indices));
3274 hr = IDirect3DIndexBuffer9_Unlock(ib);
3275 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3277 hr = IDirect3DDevice9_SetIndices(device, ib);
3278 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3279 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3280 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3281 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3282 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3284 /* Now destroy the bound index buffer and draw again */
3285 ref = IDirect3DIndexBuffer9_Release(ib);
3286 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3289 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3291 hr = IDirect3DDevice9_BeginScene(device);
3292 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3293 if(SUCCEEDED(hr))
3295 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3296 * making assumptions about the indices or vertices
3298 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3299 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3300 hr = IDirect3DDevice9_EndScene(device);
3301 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3304 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3305 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3307 hr = IDirect3DDevice9_SetIndices(device, NULL);
3308 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3309 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3310 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3312 /* Index buffer was already destroyed as part of the test */
3313 IDirect3DVertexBuffer9_Release(vb);
3316 static void float_texture_test(IDirect3DDevice9 *device)
3318 IDirect3D9 *d3d = NULL;
3319 HRESULT hr;
3320 IDirect3DTexture9 *texture = NULL;
3321 D3DLOCKED_RECT lr;
3322 float *data;
3323 DWORD color;
3324 float quad[] = {
3325 -1.0, -1.0, 0.1, 0.0, 0.0,
3326 -1.0, 1.0, 0.1, 0.0, 1.0,
3327 1.0, -1.0, 0.1, 1.0, 0.0,
3328 1.0, 1.0, 0.1, 1.0, 1.0,
3331 memset(&lr, 0, sizeof(lr));
3332 IDirect3DDevice9_GetDirect3D(device, &d3d);
3333 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3334 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3335 skip("D3DFMT_R32F textures not supported\n");
3336 goto out;
3339 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3340 D3DPOOL_MANAGED, &texture, NULL);
3341 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3342 if(!texture) {
3343 skip("Failed to create R32F texture\n");
3344 goto out;
3347 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3348 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3349 data = lr.pBits;
3350 *data = 0.0;
3351 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3352 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3354 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3355 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3357 hr = IDirect3DDevice9_BeginScene(device);
3358 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3359 if(SUCCEEDED(hr))
3361 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3362 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3365 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3367 hr = IDirect3DDevice9_EndScene(device);
3368 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3370 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3373 color = getPixelColor(device, 240, 320);
3374 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3376 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3377 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3379 out:
3380 if(texture) IDirect3DTexture9_Release(texture);
3381 IDirect3D9_Release(d3d);
3384 static void g16r16_texture_test(IDirect3DDevice9 *device)
3386 IDirect3D9 *d3d = NULL;
3387 HRESULT hr;
3388 IDirect3DTexture9 *texture = NULL;
3389 D3DLOCKED_RECT lr;
3390 DWORD *data;
3391 DWORD color;
3392 float quad[] = {
3393 -1.0, -1.0, 0.1, 0.0, 0.0,
3394 -1.0, 1.0, 0.1, 0.0, 1.0,
3395 1.0, -1.0, 0.1, 1.0, 0.0,
3396 1.0, 1.0, 0.1, 1.0, 1.0,
3399 memset(&lr, 0, sizeof(lr));
3400 IDirect3DDevice9_GetDirect3D(device, &d3d);
3401 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3402 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3403 skip("D3DFMT_G16R16 textures not supported\n");
3404 goto out;
3407 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3408 D3DPOOL_MANAGED, &texture, NULL);
3409 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3410 if(!texture) {
3411 skip("Failed to create D3DFMT_G16R16 texture\n");
3412 goto out;
3415 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3416 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3417 data = lr.pBits;
3418 *data = 0x0f00f000;
3419 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3420 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3422 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3425 hr = IDirect3DDevice9_BeginScene(device);
3426 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3427 if(SUCCEEDED(hr))
3429 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3430 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3433 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3435 hr = IDirect3DDevice9_EndScene(device);
3436 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3438 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3439 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3441 color = getPixelColor(device, 240, 320);
3442 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3443 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3448 out:
3449 if(texture) IDirect3DTexture9_Release(texture);
3450 IDirect3D9_Release(d3d);
3453 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3455 HRESULT hr;
3456 IDirect3D9 *d3d;
3457 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3458 D3DCAPS9 caps;
3459 IDirect3DTexture9 *texture = NULL;
3460 IDirect3DVolumeTexture9 *volume = NULL;
3461 unsigned int x, y, z;
3462 D3DLOCKED_RECT lr;
3463 D3DLOCKED_BOX lb;
3464 DWORD color;
3465 UINT w, h;
3466 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3467 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3468 0.0, 1.0, 0.0, 0.0,
3469 0.0, 0.0, 1.0, 0.0,
3470 0.0, 0.0, 0.0, 1.0};
3471 static const D3DVERTEXELEMENT9 decl_elements[] = {
3472 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3473 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3474 D3DDECL_END()
3476 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3477 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3478 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3479 D3DDECL_END()
3481 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3482 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3483 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3484 D3DDECL_END()
3486 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3487 0x00, 0xff, 0x00, 0x00,
3488 0x00, 0x00, 0x00, 0x00,
3489 0x00, 0x00, 0x00, 0x00};
3491 memset(&lr, 0, sizeof(lr));
3492 memset(&lb, 0, sizeof(lb));
3493 IDirect3DDevice9_GetDirect3D(device, &d3d);
3494 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3495 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3496 fmt = D3DFMT_A16B16G16R16;
3498 IDirect3D9_Release(d3d);
3500 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3502 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3503 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3504 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3506 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3507 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3508 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3509 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3510 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3511 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3512 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3513 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3514 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3515 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3516 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3517 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3518 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3519 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3521 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3523 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3525 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3526 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3527 w = min(1024, caps.MaxTextureWidth);
3528 h = min(1024, caps.MaxTextureHeight);
3529 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3530 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3531 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3532 if(!texture) {
3533 skip("Failed to create the test texture\n");
3534 return;
3537 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3538 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3539 * 1.0 in red and green for the x and y coords
3541 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3542 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3543 for(y = 0; y < h; y++) {
3544 for(x = 0; x < w; x++) {
3545 double r_f = (double) y / (double) h;
3546 double g_f = (double) x / (double) w;
3547 if(fmt == D3DFMT_A16B16G16R16) {
3548 unsigned short r, g;
3549 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3550 r = (unsigned short) (r_f * 65536.0);
3551 g = (unsigned short) (g_f * 65536.0);
3552 dst[0] = r;
3553 dst[1] = g;
3554 dst[2] = 0;
3555 dst[3] = 65535;
3556 } else {
3557 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3558 unsigned char r = (unsigned char) (r_f * 255.0);
3559 unsigned char g = (unsigned char) (g_f * 255.0);
3560 dst[0] = 0;
3561 dst[1] = g;
3562 dst[2] = r;
3563 dst[3] = 255;
3567 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3568 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3569 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3570 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3574 hr = IDirect3DDevice9_BeginScene(device);
3575 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3576 if(SUCCEEDED(hr))
3578 float quad1[] = {
3579 -1.0, -1.0, 0.1, 1.0, 1.0,
3580 -1.0, 0.0, 0.1, 1.0, 1.0,
3581 0.0, -1.0, 0.1, 1.0, 1.0,
3582 0.0, 0.0, 0.1, 1.0, 1.0,
3584 float quad2[] = {
3585 -1.0, 0.0, 0.1, 1.0, 1.0,
3586 -1.0, 1.0, 0.1, 1.0, 1.0,
3587 0.0, 0.0, 0.1, 1.0, 1.0,
3588 0.0, 1.0, 0.1, 1.0, 1.0,
3590 float quad3[] = {
3591 0.0, 0.0, 0.1, 0.5, 0.5,
3592 0.0, 1.0, 0.1, 0.5, 0.5,
3593 1.0, 0.0, 0.1, 0.5, 0.5,
3594 1.0, 1.0, 0.1, 0.5, 0.5,
3596 float quad4[] = {
3597 320, 480, 0.1, 1.0, 0.0, 1.0,
3598 320, 240, 0.1, 1.0, 0.0, 1.0,
3599 640, 480, 0.1, 1.0, 0.0, 1.0,
3600 640, 240, 0.1, 1.0, 0.0, 1.0,
3602 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3603 0.0, 0.0, 0.0, 0.0,
3604 0.0, 0.0, 0.0, 0.0,
3605 0.0, 0.0, 0.0, 0.0};
3607 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3608 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3609 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3610 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3611 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3613 /* What happens with transforms enabled? */
3614 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3615 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3617 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3619 /* What happens if 4 coords are used, but only 2 given ?*/
3620 mat[8] = 1.0;
3621 mat[13] = 1.0;
3622 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3623 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3624 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3625 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3627 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3629 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3630 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3631 * due to the coords in the vertices. (turns out red, indeed)
3633 memset(mat, 0, sizeof(mat));
3634 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3635 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3636 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3637 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3638 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3639 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3641 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3643 hr = IDirect3DDevice9_EndScene(device);
3644 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3646 color = getPixelColor(device, 160, 360);
3647 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3648 color = getPixelColor(device, 160, 120);
3649 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3650 color = getPixelColor(device, 480, 120);
3651 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3652 color = getPixelColor(device, 480, 360);
3653 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3654 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3657 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3658 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3660 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3661 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3662 hr = IDirect3DDevice9_BeginScene(device);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3664 if(SUCCEEDED(hr))
3666 float quad1[] = {
3667 -1.0, -1.0, 0.1, 0.8, 0.2,
3668 -1.0, 0.0, 0.1, 0.8, 0.2,
3669 0.0, -1.0, 0.1, 0.8, 0.2,
3670 0.0, 0.0, 0.1, 0.8, 0.2,
3672 float quad2[] = {
3673 -1.0, 0.0, 0.1, 0.5, 1.0,
3674 -1.0, 1.0, 0.1, 0.5, 1.0,
3675 0.0, 0.0, 0.1, 0.5, 1.0,
3676 0.0, 1.0, 0.1, 0.5, 1.0,
3678 float quad3[] = {
3679 0.0, 0.0, 0.1, 0.5, 1.0,
3680 0.0, 1.0, 0.1, 0.5, 1.0,
3681 1.0, 0.0, 0.1, 0.5, 1.0,
3682 1.0, 1.0, 0.1, 0.5, 1.0,
3684 float quad4[] = {
3685 0.0, -1.0, 0.1, 0.8, 0.2,
3686 0.0, 0.0, 0.1, 0.8, 0.2,
3687 1.0, -1.0, 0.1, 0.8, 0.2,
3688 1.0, 0.0, 0.1, 0.8, 0.2,
3690 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3691 0.0, 0.0, 0.0, 0.0,
3692 0.0, 1.0, 0.0, 0.0,
3693 0.0, 0.0, 0.0, 0.0};
3695 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3697 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3699 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3700 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3705 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3706 * it behaves like COUNT2 because normal textures require 2 coords
3708 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3709 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3710 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3711 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3713 /* Just to be sure, the same as quad2 above */
3714 memset(mat, 0, sizeof(mat));
3715 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3718 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3720 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3722 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3723 * used? And what happens to the first?
3725 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3726 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3728 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3730 hr = IDirect3DDevice9_EndScene(device);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3733 color = getPixelColor(device, 160, 360);
3734 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3735 color = getPixelColor(device, 160, 120);
3736 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3737 color = getPixelColor(device, 480, 120);
3738 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3739 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3740 color = getPixelColor(device, 480, 360);
3741 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3742 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3743 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3744 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3746 IDirect3DTexture9_Release(texture);
3748 /* Test projected textures, without any fancy matrices */
3749 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3750 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3751 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3753 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3754 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3755 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3756 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3758 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3759 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3760 for(x = 0; x < 4; x++) {
3761 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3763 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3764 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3765 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3768 hr = IDirect3DDevice9_BeginScene(device);
3769 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3770 if(SUCCEEDED(hr))
3772 const float proj_quads[] = {
3773 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3774 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3775 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3776 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3777 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3778 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3779 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3780 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3783 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3784 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3786 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3788 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3789 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3791 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3793 hr = IDirect3DDevice9_EndScene(device);
3794 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3797 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3799 IDirect3DTexture9_Release(texture);
3801 color = getPixelColor(device, 158, 118);
3802 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3803 color = getPixelColor(device, 162, 118);
3804 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3805 color = getPixelColor(device, 158, 122);
3806 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3807 color = getPixelColor(device, 162, 122);
3808 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3810 color = getPixelColor(device, 158, 178);
3811 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3812 color = getPixelColor(device, 162, 178);
3813 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3814 color = getPixelColor(device, 158, 182);
3815 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3816 color = getPixelColor(device, 162, 182);
3817 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3819 color = getPixelColor(device, 318, 118);
3820 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3821 color = getPixelColor(device, 322, 118);
3822 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3823 color = getPixelColor(device, 318, 122);
3824 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3825 color = getPixelColor(device, 322, 122);
3826 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3828 color = getPixelColor(device, 318, 178);
3829 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3830 color = getPixelColor(device, 322, 178);
3831 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3832 color = getPixelColor(device, 318, 182);
3833 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3834 color = getPixelColor(device, 322, 182);
3835 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3837 color = getPixelColor(device, 238, 298);
3838 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3839 color = getPixelColor(device, 242, 298);
3840 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3841 color = getPixelColor(device, 238, 302);
3842 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3843 color = getPixelColor(device, 242, 302);
3844 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3846 color = getPixelColor(device, 238, 388);
3847 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3848 color = getPixelColor(device, 242, 388);
3849 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3850 color = getPixelColor(device, 238, 392);
3851 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3852 color = getPixelColor(device, 242, 392);
3853 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3855 color = getPixelColor(device, 478, 298);
3856 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3857 color = getPixelColor(device, 482, 298);
3858 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3859 color = getPixelColor(device, 478, 302);
3860 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3861 color = getPixelColor(device, 482, 302);
3862 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3864 color = getPixelColor(device, 478, 388);
3865 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3866 color = getPixelColor(device, 482, 388);
3867 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3868 color = getPixelColor(device, 478, 392);
3869 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3870 color = getPixelColor(device, 482, 392);
3871 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3873 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3878 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3879 * Thus watch out if sampling from texels between 0 and 1.
3881 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3882 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3883 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3884 if(!volume) {
3885 skip("Failed to create a volume texture\n");
3886 goto out;
3889 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3890 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3891 for(z = 0; z < 32; z++) {
3892 for(y = 0; y < 32; y++) {
3893 for(x = 0; x < 32; x++) {
3894 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3895 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3896 float r_f = (float) x / 31.0;
3897 float g_f = (float) y / 31.0;
3898 float b_f = (float) z / 31.0;
3900 if(fmt == D3DFMT_A16B16G16R16) {
3901 unsigned short *mem_s = mem;
3902 mem_s[0] = r_f * 65535.0;
3903 mem_s[1] = g_f * 65535.0;
3904 mem_s[2] = b_f * 65535.0;
3905 mem_s[3] = 65535;
3906 } else {
3907 unsigned char *mem_c = mem;
3908 mem_c[0] = b_f * 255.0;
3909 mem_c[1] = g_f * 255.0;
3910 mem_c[2] = r_f * 255.0;
3911 mem_c[3] = 255;
3916 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3917 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3919 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3920 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3922 hr = IDirect3DDevice9_BeginScene(device);
3923 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3924 if(SUCCEEDED(hr))
3926 float quad1[] = {
3927 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3928 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3929 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3930 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3932 float quad2[] = {
3933 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3934 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3935 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3936 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3938 float quad3[] = {
3939 0.0, 0.0, 0.1, 0.0, 0.0,
3940 0.0, 1.0, 0.1, 0.0, 0.0,
3941 1.0, 0.0, 0.1, 0.0, 0.0,
3942 1.0, 1.0, 0.1, 0.0, 0.0
3944 float quad4[] = {
3945 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3946 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3947 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3948 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3950 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3951 0.0, 0.0, 1.0, 0.0,
3952 0.0, 1.0, 0.0, 0.0,
3953 0.0, 0.0, 0.0, 1.0};
3954 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3955 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3957 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3958 * values
3960 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3961 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3962 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3963 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3965 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3967 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3968 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3969 * otherwise the w will be missing(blue).
3970 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3971 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3973 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3974 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3976 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3978 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3979 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3980 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3981 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3982 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3983 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3984 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3986 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3988 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3989 * disable. ATI extends it up to the amount of values needed for the volume texture
3991 memset(mat, 0, sizeof(mat));
3992 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3993 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3994 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3995 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3996 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3997 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3999 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4001 hr = IDirect3DDevice9_EndScene(device);
4002 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4005 color = getPixelColor(device, 160, 360);
4006 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4007 color = getPixelColor(device, 160, 120);
4008 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4009 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4010 color = getPixelColor(device, 480, 120);
4011 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4012 color = getPixelColor(device, 480, 360);
4013 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4015 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4016 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4019 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4020 hr = IDirect3DDevice9_BeginScene(device);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4022 if(SUCCEEDED(hr))
4024 float quad1[] = {
4025 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4026 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4027 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4028 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4030 float quad2[] = {
4031 -1.0, 0.0, 0.1,
4032 -1.0, 1.0, 0.1,
4033 0.0, 0.0, 0.1,
4034 0.0, 1.0, 0.1,
4036 float quad3[] = {
4037 0.0, 0.0, 0.1, 1.0,
4038 0.0, 1.0, 0.1, 1.0,
4039 1.0, 0.0, 0.1, 1.0,
4040 1.0, 1.0, 0.1, 1.0
4042 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4043 0.0, 0.0, 0.0, 0.0,
4044 0.0, 0.0, 0.0, 0.0,
4045 0.0, 1.0, 0.0, 0.0};
4046 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4047 1.0, 0.0, 0.0, 0.0,
4048 0.0, 1.0, 0.0, 0.0,
4049 0.0, 0.0, 1.0, 0.0};
4050 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4051 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4053 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4054 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4055 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4056 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4057 * 4th *input* coordinate.
4059 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4061 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4062 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4064 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4066 /* None passed */
4067 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4068 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4069 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4070 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4072 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4074 /* 4 used, 1 passed */
4075 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4076 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4077 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4078 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4080 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4082 hr = IDirect3DDevice9_EndScene(device);
4083 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4085 color = getPixelColor(device, 160, 360);
4086 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4087 color = getPixelColor(device, 160, 120);
4088 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4089 color = getPixelColor(device, 480, 120);
4090 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4091 /* Quad4: unused */
4093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4094 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4096 IDirect3DVolumeTexture9_Release(volume);
4098 out:
4099 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4100 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4101 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4102 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4103 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4104 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4105 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4106 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4107 IDirect3DVertexDeclaration9_Release(decl);
4108 IDirect3DVertexDeclaration9_Release(decl2);
4109 IDirect3DVertexDeclaration9_Release(decl3);
4112 static void texdepth_test(IDirect3DDevice9 *device)
4114 IDirect3DPixelShader9 *shader;
4115 HRESULT hr;
4116 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4117 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4118 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4119 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4120 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4121 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4122 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4123 DWORD shader_code[] = {
4124 0xffff0104, /* ps_1_4 */
4125 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4126 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4127 0x0000fffd, /* phase */
4128 0x00000057, 0x800f0005, /* texdepth r5 */
4129 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4130 0x0000ffff /* end */
4132 DWORD color;
4133 float vertex[] = {
4134 -1.0, -1.0, 0.0,
4135 1.0, -1.0, 1.0,
4136 -1.0, 1.0, 0.0,
4137 1.0, 1.0, 1.0
4140 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4141 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4148 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4151 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4152 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4154 /* Fill the depth buffer with a gradient */
4155 hr = IDirect3DDevice9_BeginScene(device);
4156 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4157 if(SUCCEEDED(hr))
4159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4160 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4161 hr = IDirect3DDevice9_EndScene(device);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4165 /* Now perform the actual tests. Same geometry, but with the shader */
4166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4167 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4169 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4170 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4173 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4174 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4175 hr = IDirect3DDevice9_BeginScene(device);
4176 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4177 if(SUCCEEDED(hr))
4179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4180 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4182 hr = IDirect3DDevice9_EndScene(device);
4183 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4186 color = getPixelColor(device, 158, 240);
4187 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4188 color = getPixelColor(device, 162, 240);
4189 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4191 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4192 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4194 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4195 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4197 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4198 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4199 hr = IDirect3DDevice9_BeginScene(device);
4200 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4201 if(SUCCEEDED(hr))
4203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4204 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4206 hr = IDirect3DDevice9_EndScene(device);
4207 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4210 color = getPixelColor(device, 318, 240);
4211 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4212 color = getPixelColor(device, 322, 240);
4213 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4215 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4216 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4218 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4219 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4221 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4222 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4223 hr = IDirect3DDevice9_BeginScene(device);
4224 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4225 if(SUCCEEDED(hr))
4227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4228 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4230 hr = IDirect3DDevice9_EndScene(device);
4231 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4234 color = getPixelColor(device, 1, 240);
4235 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4237 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4238 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4240 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4241 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4243 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4245 hr = IDirect3DDevice9_BeginScene(device);
4246 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4247 if(SUCCEEDED(hr))
4249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4250 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4252 hr = IDirect3DDevice9_EndScene(device);
4253 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4255 color = getPixelColor(device, 318, 240);
4256 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4257 color = getPixelColor(device, 322, 240);
4258 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4260 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4261 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4264 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4266 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4267 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4268 hr = IDirect3DDevice9_BeginScene(device);
4269 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4270 if(SUCCEEDED(hr))
4272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4273 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4275 hr = IDirect3DDevice9_EndScene(device);
4276 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4279 color = getPixelColor(device, 1, 240);
4280 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4282 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4283 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4285 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4286 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4288 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4290 hr = IDirect3DDevice9_BeginScene(device);
4291 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4292 if(SUCCEEDED(hr))
4294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4295 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4297 hr = IDirect3DDevice9_EndScene(device);
4298 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4301 color = getPixelColor(device, 638, 240);
4302 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4304 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4305 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4307 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4308 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4310 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4311 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4312 hr = IDirect3DDevice9_BeginScene(device);
4313 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4314 if(SUCCEEDED(hr))
4316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4317 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4319 hr = IDirect3DDevice9_EndScene(device);
4320 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4323 color = getPixelColor(device, 638, 240);
4324 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4326 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4327 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4329 /* Cleanup */
4330 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4331 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4332 IDirect3DPixelShader9_Release(shader);
4334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4337 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4340 static void texkill_test(IDirect3DDevice9 *device)
4342 IDirect3DPixelShader9 *shader;
4343 HRESULT hr;
4344 DWORD color;
4346 const float vertex[] = {
4347 /* bottom top right left */
4348 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4349 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4350 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4351 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4354 DWORD shader_code_11[] = {
4355 0xffff0101, /* ps_1_1 */
4356 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4357 0x00000041, 0xb00f0000, /* texkill t0 */
4358 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4359 0x0000ffff /* end */
4361 DWORD shader_code_20[] = {
4362 0xffff0200, /* ps_2_0 */
4363 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4364 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4365 0x01000041, 0xb00f0000, /* texkill t0 */
4366 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4367 0x0000ffff /* end */
4370 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4371 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4372 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4373 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4375 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4376 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4377 hr = IDirect3DDevice9_BeginScene(device);
4378 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4379 if(SUCCEEDED(hr))
4381 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4382 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4384 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4385 hr = IDirect3DDevice9_EndScene(device);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4388 color = getPixelColor(device, 63, 46);
4389 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4390 color = getPixelColor(device, 66, 46);
4391 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4392 color = getPixelColor(device, 63, 49);
4393 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4394 color = getPixelColor(device, 66, 49);
4395 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4397 color = getPixelColor(device, 578, 46);
4398 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4399 color = getPixelColor(device, 575, 46);
4400 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4401 color = getPixelColor(device, 578, 49);
4402 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4403 color = getPixelColor(device, 575, 49);
4404 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4406 color = getPixelColor(device, 63, 430);
4407 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4408 color = getPixelColor(device, 63, 433);
4409 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4410 color = getPixelColor(device, 66, 433);
4411 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4412 color = getPixelColor(device, 66, 430);
4413 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4415 color = getPixelColor(device, 578, 430);
4416 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4417 color = getPixelColor(device, 578, 433);
4418 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4419 color = getPixelColor(device, 575, 433);
4420 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4421 color = getPixelColor(device, 575, 430);
4422 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4424 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4425 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4427 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4428 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4429 IDirect3DPixelShader9_Release(shader);
4431 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4432 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4433 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4434 if(FAILED(hr)) {
4435 skip("Failed to create 2.0 test shader, most likely not supported\n");
4436 return;
4439 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4440 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader 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, 7 * sizeof(float));
4446 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447 hr = IDirect3DDevice9_EndScene(device);
4448 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4451 color = getPixelColor(device, 63, 46);
4452 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4453 color = getPixelColor(device, 66, 46);
4454 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4455 color = getPixelColor(device, 63, 49);
4456 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4457 color = getPixelColor(device, 66, 49);
4458 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4460 color = getPixelColor(device, 578, 46);
4461 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4462 color = getPixelColor(device, 575, 46);
4463 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4464 color = getPixelColor(device, 578, 49);
4465 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4466 color = getPixelColor(device, 575, 49);
4467 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4469 color = getPixelColor(device, 63, 430);
4470 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4471 color = getPixelColor(device, 63, 433);
4472 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4473 color = getPixelColor(device, 66, 433);
4474 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4475 color = getPixelColor(device, 66, 430);
4476 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4478 color = getPixelColor(device, 578, 430);
4479 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4480 color = getPixelColor(device, 578, 433);
4481 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4482 color = getPixelColor(device, 575, 433);
4483 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4484 color = getPixelColor(device, 575, 430);
4485 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4488 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4490 /* Cleanup */
4491 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4492 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4493 IDirect3DPixelShader9_Release(shader);
4496 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4498 IDirect3D9 *d3d9;
4499 HRESULT hr;
4500 IDirect3DTexture9 *texture;
4501 IDirect3DPixelShader9 *shader;
4502 IDirect3DPixelShader9 *shader2;
4503 D3DLOCKED_RECT lr;
4504 DWORD color;
4505 DWORD shader_code[] = {
4506 0xffff0101, /* ps_1_1 */
4507 0x00000042, 0xb00f0000, /* tex t0 */
4508 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4509 0x0000ffff /* end */
4511 DWORD shader_code2[] = {
4512 0xffff0101, /* ps_1_1 */
4513 0x00000042, 0xb00f0000, /* tex t0 */
4514 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4515 0x0000ffff /* end */
4518 float quad[] = {
4519 -1.0, -1.0, 0.1, 0.5, 0.5,
4520 1.0, -1.0, 0.1, 0.5, 0.5,
4521 -1.0, 1.0, 0.1, 0.5, 0.5,
4522 1.0, 1.0, 0.1, 0.5, 0.5,
4525 memset(&lr, 0, sizeof(lr));
4526 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4527 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4528 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4529 IDirect3D9_Release(d3d9);
4530 if(FAILED(hr)) {
4531 skip("No D3DFMT_X8L8V8U8 support\n");
4532 return;
4535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4536 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4538 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4539 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4540 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4541 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4542 *((DWORD *) lr.pBits) = 0x11ca3141;
4543 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4544 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4546 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4548 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4549 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4551 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4553 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4554 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4556 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4558 hr = IDirect3DDevice9_BeginScene(device);
4559 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4560 if(SUCCEEDED(hr))
4562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4563 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4565 hr = IDirect3DDevice9_EndScene(device);
4566 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4568 color = getPixelColor(device, 578, 430);
4569 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4570 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4571 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4572 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4574 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4575 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4576 hr = IDirect3DDevice9_BeginScene(device);
4577 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4578 if(SUCCEEDED(hr))
4580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4581 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4583 hr = IDirect3DDevice9_EndScene(device);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4586 color = getPixelColor(device, 578, 430);
4587 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4588 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4589 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4591 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4592 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4593 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4594 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4595 IDirect3DPixelShader9_Release(shader);
4596 IDirect3DPixelShader9_Release(shader2);
4597 IDirect3DTexture9_Release(texture);
4600 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4602 HRESULT hr;
4603 IDirect3D9 *d3d;
4604 IDirect3DTexture9 *texture = NULL;
4605 IDirect3DSurface9 *surface;
4606 DWORD color;
4607 const RECT r1 = {256, 256, 512, 512};
4608 const RECT r2 = {512, 256, 768, 512};
4609 const RECT r3 = {256, 512, 512, 768};
4610 const RECT r4 = {512, 512, 768, 768};
4611 unsigned int x, y;
4612 D3DLOCKED_RECT lr;
4613 memset(&lr, 0, sizeof(lr));
4615 IDirect3DDevice9_GetDirect3D(device, &d3d);
4616 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4617 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4618 skip("No autogenmipmap support\n");
4619 IDirect3D9_Release(d3d);
4620 return;
4622 IDirect3D9_Release(d3d);
4624 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4625 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4627 /* Make the mipmap big, so that a smaller mipmap is used
4629 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4630 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4631 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4633 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4634 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4635 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4636 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4637 for(y = 0; y < 1024; y++) {
4638 for(x = 0; x < 1024; x++) {
4639 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4640 POINT pt;
4642 pt.x = x;
4643 pt.y = y;
4644 if(PtInRect(&r1, pt)) {
4645 *dst = 0xffff0000;
4646 } else if(PtInRect(&r2, pt)) {
4647 *dst = 0xff00ff00;
4648 } else if(PtInRect(&r3, pt)) {
4649 *dst = 0xff0000ff;
4650 } else if(PtInRect(&r4, pt)) {
4651 *dst = 0xff000000;
4652 } else {
4653 *dst = 0xffffffff;
4657 hr = IDirect3DSurface9_UnlockRect(surface);
4658 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4659 IDirect3DSurface9_Release(surface);
4661 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4662 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4663 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4664 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4666 hr = IDirect3DDevice9_BeginScene(device);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4668 if(SUCCEEDED(hr)) {
4669 const float quad[] = {
4670 -0.5, -0.5, 0.1, 0.0, 0.0,
4671 -0.5, 0.5, 0.1, 0.0, 1.0,
4672 0.5, -0.5, 0.1, 1.0, 0.0,
4673 0.5, 0.5, 0.1, 1.0, 1.0
4676 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4679 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4680 hr = IDirect3DDevice9_EndScene(device);
4681 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4683 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4684 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4685 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4686 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4687 IDirect3DTexture9_Release(texture);
4689 color = getPixelColor(device, 200, 200);
4690 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4691 color = getPixelColor(device, 280, 200);
4692 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4693 color = getPixelColor(device, 360, 200);
4694 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4695 color = getPixelColor(device, 440, 200);
4696 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4697 color = getPixelColor(device, 200, 270);
4698 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4699 color = getPixelColor(device, 280, 270);
4700 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4701 color = getPixelColor(device, 360, 270);
4702 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4703 color = getPixelColor(device, 440, 270);
4704 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4705 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4706 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4709 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4711 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4712 IDirect3DVertexDeclaration9 *decl;
4713 HRESULT hr;
4714 DWORD color;
4715 DWORD shader_code_11[] = {
4716 0xfffe0101, /* vs_1_1 */
4717 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4718 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4719 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4720 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4721 0x0000ffff /* end */
4723 DWORD shader_code_11_2[] = {
4724 0xfffe0101, /* vs_1_1 */
4725 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4726 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4727 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4728 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4729 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4730 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4731 0x0000ffff /* end */
4733 DWORD shader_code_20[] = {
4734 0xfffe0200, /* vs_2_0 */
4735 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4736 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4737 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4738 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4739 0x0000ffff /* end */
4741 DWORD shader_code_20_2[] = {
4742 0xfffe0200, /* vs_2_0 */
4743 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4744 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4745 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4746 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4747 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4748 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4749 0x0000ffff /* end */
4751 static const D3DVERTEXELEMENT9 decl_elements[] = {
4752 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4753 D3DDECL_END()
4755 float quad1[] = {
4756 -1.0, -1.0, 0.1,
4757 0.0, -1.0, 0.1,
4758 -1.0, 0.0, 0.1,
4759 0.0, 0.0, 0.1
4761 float quad2[] = {
4762 0.0, -1.0, 0.1,
4763 1.0, -1.0, 0.1,
4764 0.0, 0.0, 0.1,
4765 1.0, 0.0, 0.1
4767 float quad3[] = {
4768 0.0, 0.0, 0.1,
4769 1.0, 0.0, 0.1,
4770 0.0, 1.0, 0.1,
4771 1.0, 1.0, 0.1
4773 float quad4[] = {
4774 -1.0, 0.0, 0.1,
4775 0.0, 0.0, 0.1,
4776 -1.0, 1.0, 0.1,
4777 0.0, 1.0, 0.1
4779 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4780 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4782 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4783 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4785 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4786 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4787 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4789 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4790 if(FAILED(hr)) shader_20 = NULL;
4791 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4792 if(FAILED(hr)) shader_20_2 = NULL;
4793 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4796 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4797 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4798 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4799 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4800 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4803 hr = IDirect3DDevice9_BeginScene(device);
4804 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4805 if(SUCCEEDED(hr))
4807 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4810 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4812 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4813 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4815 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4817 if(shader_20) {
4818 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4819 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4820 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4821 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4824 if(shader_20_2) {
4825 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4828 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4831 hr = IDirect3DDevice9_EndScene(device);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4835 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4837 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4840 color = getPixelColor(device, 160, 360);
4841 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4842 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4843 color = getPixelColor(device, 480, 360);
4844 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4845 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4846 if(shader_20) {
4847 color = getPixelColor(device, 480, 120);
4848 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4849 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4851 if(shader_20_2) {
4852 color = getPixelColor(device, 160, 120);
4853 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4854 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4857 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4859 IDirect3DVertexDeclaration9_Release(decl);
4860 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4861 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4862 IDirect3DVertexShader9_Release(shader_11_2);
4863 IDirect3DVertexShader9_Release(shader_11);
4866 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4868 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4869 HRESULT hr;
4870 DWORD color;
4871 DWORD shader_code_11[] = {
4872 0xffff0101, /* ps_1_1 */
4873 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4874 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4875 0x0000ffff /* end */
4877 DWORD shader_code_12[] = {
4878 0xffff0102, /* ps_1_2 */
4879 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4880 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4881 0x0000ffff /* end */
4883 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4884 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4885 * During development of this test, 1.3 shaders were verified too
4887 DWORD shader_code_14[] = {
4888 0xffff0104, /* ps_1_4 */
4889 /* Try to make one constant local. It gets clamped too, although the binary contains
4890 * the bigger numbers
4892 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4893 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4894 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4895 0x0000ffff /* end */
4897 DWORD shader_code_20[] = {
4898 0xffff0200, /* ps_2_0 */
4899 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4900 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4901 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4902 0x0000ffff /* end */
4904 float quad1[] = {
4905 -1.0, -1.0, 0.1,
4906 0.0, -1.0, 0.1,
4907 -1.0, 0.0, 0.1,
4908 0.0, 0.0, 0.1
4910 float quad2[] = {
4911 0.0, -1.0, 0.1,
4912 1.0, -1.0, 0.1,
4913 0.0, 0.0, 0.1,
4914 1.0, 0.0, 0.1
4916 float quad3[] = {
4917 0.0, 0.0, 0.1,
4918 1.0, 0.0, 0.1,
4919 0.0, 1.0, 0.1,
4920 1.0, 1.0, 0.1
4922 float quad4[] = {
4923 -1.0, 0.0, 0.1,
4924 0.0, 0.0, 0.1,
4925 -1.0, 1.0, 0.1,
4926 0.0, 1.0, 0.1
4928 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4929 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4932 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4934 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4935 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4936 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4937 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4938 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4939 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4941 if(FAILED(hr)) shader_20 = NULL;
4943 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4944 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4945 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4946 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4950 hr = IDirect3DDevice9_BeginScene(device);
4951 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4952 if(SUCCEEDED(hr))
4954 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4957 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4959 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4960 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4962 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4964 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4967 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4969 if(shader_20) {
4970 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4971 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4973 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4976 hr = IDirect3DDevice9_EndScene(device);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4979 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4980 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4982 color = getPixelColor(device, 160, 360);
4983 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4984 "quad 1 has color %08x, expected 0x00808000\n", color);
4985 color = getPixelColor(device, 480, 360);
4986 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4987 "quad 2 has color %08x, expected 0x00808000\n", color);
4988 color = getPixelColor(device, 480, 120);
4989 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4990 "quad 3 has color %08x, expected 0x00808000\n", color);
4991 if(shader_20) {
4992 color = getPixelColor(device, 160, 120);
4993 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4994 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4999 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5000 IDirect3DPixelShader9_Release(shader_14);
5001 IDirect3DPixelShader9_Release(shader_12);
5002 IDirect3DPixelShader9_Release(shader_11);
5005 static void dp2add_ps_test(IDirect3DDevice9 *device)
5007 IDirect3DPixelShader9 *shader_dp2add = NULL;
5008 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5009 HRESULT hr;
5010 DWORD color;
5012 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5013 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5014 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5015 * r0 first.
5016 * The result here for the r,g,b components should be roughly 0.5:
5017 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5018 static const DWORD shader_code_dp2add[] = {
5019 0xffff0200, /* ps_2_0 */
5020 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5022 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5023 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5025 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5026 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5027 0x0000ffff /* end */
5030 /* Test the _sat modifier, too. Result here should be:
5031 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5032 * _SAT: ==> 1.0
5033 * ADD: (1.0 + -0.5) = 0.5
5035 static const DWORD shader_code_dp2add_sat[] = {
5036 0xffff0200, /* ps_2_0 */
5037 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5039 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5040 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5041 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5043 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5044 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5045 0x0000ffff /* end */
5048 const float quad[] = {
5049 -1.0, -1.0, 0.1,
5050 1.0, -1.0, 0.1,
5051 -1.0, 1.0, 0.1,
5052 1.0, 1.0, 0.1
5056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5057 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5059 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5060 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5062 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5065 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5066 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5068 if (shader_dp2add) {
5070 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5071 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5073 hr = IDirect3DDevice9_BeginScene(device);
5074 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5075 if(SUCCEEDED(hr))
5077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5078 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5080 hr = IDirect3DDevice9_EndScene(device);
5081 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5084 color = getPixelColor(device, 360, 240);
5085 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5086 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5088 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5089 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5091 IDirect3DPixelShader9_Release(shader_dp2add);
5092 } else {
5093 skip("dp2add shader creation failed\n");
5096 if (shader_dp2add_sat) {
5098 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5099 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5101 hr = IDirect3DDevice9_BeginScene(device);
5102 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5103 if(SUCCEEDED(hr))
5105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5106 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5108 hr = IDirect3DDevice9_EndScene(device);
5109 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5112 color = getPixelColor(device, 360, 240);
5113 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5114 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5116 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5117 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5119 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5120 } else {
5121 skip("dp2add shader creation failed\n");
5124 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5125 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5128 static void cnd_test(IDirect3DDevice9 *device)
5130 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5131 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5132 HRESULT hr;
5133 DWORD color;
5134 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5135 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5136 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5138 DWORD shader_code_11[] = {
5139 0xffff0101, /* ps_1_1 */
5140 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5141 0x00000040, 0xb00f0000, /* texcoord t0 */
5142 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5143 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5144 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5145 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5146 0x0000ffff /* end */
5148 DWORD shader_code_12[] = {
5149 0xffff0102, /* ps_1_2 */
5150 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5151 0x00000040, 0xb00f0000, /* texcoord t0 */
5152 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5153 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5154 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5155 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5156 0x0000ffff /* end */
5158 DWORD shader_code_13[] = {
5159 0xffff0103, /* ps_1_3 */
5160 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5161 0x00000040, 0xb00f0000, /* texcoord t0 */
5162 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5163 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5164 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5165 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5166 0x0000ffff /* end */
5168 DWORD shader_code_14[] = {
5169 0xffff0104, /* ps_1_3 */
5170 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5171 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5172 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5173 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5174 0x0000ffff /* end */
5177 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5178 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5179 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5180 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5181 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5182 * good enough.
5184 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5185 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5186 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5187 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5189 DWORD shader_code_11_coissue[] = {
5190 0xffff0101, /* ps_1_1 */
5191 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5192 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5193 0x00000040, 0xb00f0000, /* texcoord t0 */
5194 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5195 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5196 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5197 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5198 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5199 /* 0x40000000 = D3DSI_COISSUE */
5200 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5201 0x0000ffff /* end */
5203 DWORD shader_code_12_coissue[] = {
5204 0xffff0102, /* ps_1_2 */
5205 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5206 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5207 0x00000040, 0xb00f0000, /* texcoord t0 */
5208 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5209 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5210 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5211 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5212 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5213 /* 0x40000000 = D3DSI_COISSUE */
5214 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5215 0x0000ffff /* end */
5217 DWORD shader_code_13_coissue[] = {
5218 0xffff0103, /* ps_1_3 */
5219 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5220 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5221 0x00000040, 0xb00f0000, /* texcoord t0 */
5222 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5223 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5224 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5225 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5226 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5227 /* 0x40000000 = D3DSI_COISSUE */
5228 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5229 0x0000ffff /* end */
5231 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5232 * compare against 0.5
5234 DWORD shader_code_14_coissue[] = {
5235 0xffff0104, /* ps_1_4 */
5236 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5237 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5238 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5239 /* 0x40000000 = D3DSI_COISSUE */
5240 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5241 0x0000ffff /* end */
5243 float quad1[] = {
5244 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5245 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5246 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5247 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5249 float quad2[] = {
5250 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5251 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5252 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5253 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5255 float quad3[] = {
5256 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5257 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5258 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5259 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5261 float quad4[] = {
5262 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5263 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5264 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5265 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5267 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5268 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5269 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5270 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5272 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5273 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5275 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5276 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5277 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5278 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5279 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5280 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5281 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5282 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5283 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5284 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5285 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5287 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5288 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5289 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5290 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5292 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5293 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5294 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5296 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5297 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5299 hr = IDirect3DDevice9_BeginScene(device);
5300 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5301 if(SUCCEEDED(hr))
5303 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5306 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5308 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5309 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5311 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5313 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5314 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5315 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5316 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5318 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5319 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5321 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323 hr = IDirect3DDevice9_EndScene(device);
5324 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5327 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5328 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5330 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5331 color = getPixelColor(device, 158, 118);
5332 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5333 color = getPixelColor(device, 162, 118);
5334 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5335 color = getPixelColor(device, 158, 122);
5336 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5337 color = getPixelColor(device, 162, 122);
5338 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5340 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5341 color = getPixelColor(device, 158, 358);
5342 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5343 color = getPixelColor(device, 162, 358);
5344 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5345 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5346 color = getPixelColor(device, 158, 362);
5347 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5348 color = getPixelColor(device, 162, 362);
5349 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5350 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5352 /* 1.2 shader */
5353 color = getPixelColor(device, 478, 358);
5354 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5355 color = getPixelColor(device, 482, 358);
5356 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5357 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5358 color = getPixelColor(device, 478, 362);
5359 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5360 color = getPixelColor(device, 482, 362);
5361 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5362 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5364 /* 1.3 shader */
5365 color = getPixelColor(device, 478, 118);
5366 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5367 color = getPixelColor(device, 482, 118);
5368 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5369 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5370 color = getPixelColor(device, 478, 122);
5371 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5372 color = getPixelColor(device, 482, 122);
5373 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5374 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5376 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5377 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5379 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5380 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5381 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5382 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5383 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5384 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5386 hr = IDirect3DDevice9_BeginScene(device);
5387 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5388 if(SUCCEEDED(hr))
5390 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5391 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5393 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5395 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5396 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5398 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5400 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5401 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5403 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5405 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5406 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5408 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5410 hr = IDirect3DDevice9_EndScene(device);
5411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5414 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5415 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5417 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5418 * that we swapped the values in c1 and c2 to make the other tests return some color
5420 color = getPixelColor(device, 158, 118);
5421 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5422 color = getPixelColor(device, 162, 118);
5423 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5424 color = getPixelColor(device, 158, 122);
5425 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5426 color = getPixelColor(device, 162, 122);
5427 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5429 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5430 * (The Win7 nvidia driver always selects c2)
5432 color = getPixelColor(device, 158, 358);
5433 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5434 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5435 color = getPixelColor(device, 162, 358);
5436 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5437 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5438 color = getPixelColor(device, 158, 362);
5439 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5440 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5441 color = getPixelColor(device, 162, 362);
5442 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5443 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5445 /* 1.2 shader */
5446 color = getPixelColor(device, 478, 358);
5447 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5448 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5449 color = getPixelColor(device, 482, 358);
5450 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5451 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5452 color = getPixelColor(device, 478, 362);
5453 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5454 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5455 color = getPixelColor(device, 482, 362);
5456 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5457 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5459 /* 1.3 shader */
5460 color = getPixelColor(device, 478, 118);
5461 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5462 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5463 color = getPixelColor(device, 482, 118);
5464 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5465 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5466 color = getPixelColor(device, 478, 122);
5467 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5468 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5469 color = getPixelColor(device, 482, 122);
5470 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5471 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5473 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5474 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5476 IDirect3DPixelShader9_Release(shader_14_coissue);
5477 IDirect3DPixelShader9_Release(shader_13_coissue);
5478 IDirect3DPixelShader9_Release(shader_12_coissue);
5479 IDirect3DPixelShader9_Release(shader_11_coissue);
5480 IDirect3DPixelShader9_Release(shader_14);
5481 IDirect3DPixelShader9_Release(shader_13);
5482 IDirect3DPixelShader9_Release(shader_12);
5483 IDirect3DPixelShader9_Release(shader_11);
5486 static void nested_loop_test(IDirect3DDevice9 *device) {
5487 const DWORD shader_code[] = {
5488 0xffff0300, /* ps_3_0 */
5489 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5490 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5491 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5492 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5493 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5494 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5495 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5496 0x0000001d, /* endloop */
5497 0x0000001d, /* endloop */
5498 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5499 0x0000ffff /* end */
5501 const DWORD vshader_code[] = {
5502 0xfffe0300, /* vs_3_0 */
5503 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5504 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5505 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5506 0x0000ffff /* end */
5508 IDirect3DPixelShader9 *shader;
5509 IDirect3DVertexShader9 *vshader;
5510 HRESULT hr;
5511 DWORD color;
5512 const float quad[] = {
5513 -1.0, -1.0, 0.1,
5514 1.0, -1.0, 0.1,
5515 -1.0, 1.0, 0.1,
5516 1.0, 1.0, 0.1
5519 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5521 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5523 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5524 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5525 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5526 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5527 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5529 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5530 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5532 hr = IDirect3DDevice9_BeginScene(device);
5533 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5534 if(SUCCEEDED(hr))
5536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5537 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5538 hr = IDirect3DDevice9_EndScene(device);
5539 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5542 color = getPixelColor(device, 360, 240);
5543 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5544 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5546 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5547 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5549 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5550 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5551 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5552 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5553 IDirect3DPixelShader9_Release(shader);
5554 IDirect3DVertexShader9_Release(vshader);
5557 struct varying_test_struct
5559 const DWORD *shader_code;
5560 IDirect3DPixelShader9 *shader;
5561 DWORD color, color_rhw;
5562 const char *name;
5563 BOOL todo, todo_rhw;
5566 struct hugeVertex
5568 float pos_x, pos_y, pos_z, rhw;
5569 float weight_1, weight_2, weight_3, weight_4;
5570 float index_1, index_2, index_3, index_4;
5571 float normal_1, normal_2, normal_3, normal_4;
5572 float fog_1, fog_2, fog_3, fog_4;
5573 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5574 float tangent_1, tangent_2, tangent_3, tangent_4;
5575 float binormal_1, binormal_2, binormal_3, binormal_4;
5576 float depth_1, depth_2, depth_3, depth_4;
5577 DWORD diffuse, specular;
5580 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5581 /* dcl_position: fails to compile */
5582 const DWORD blendweight_code[] = {
5583 0xffff0300, /* ps_3_0 */
5584 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5585 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5586 0x0000ffff /* end */
5588 const DWORD blendindices_code[] = {
5589 0xffff0300, /* ps_3_0 */
5590 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5591 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5592 0x0000ffff /* end */
5594 const DWORD normal_code[] = {
5595 0xffff0300, /* ps_3_0 */
5596 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5597 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5598 0x0000ffff /* end */
5600 /* psize: fails? */
5601 const DWORD texcoord0_code[] = {
5602 0xffff0300, /* ps_3_0 */
5603 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5604 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5605 0x0000ffff /* end */
5607 const DWORD tangent_code[] = {
5608 0xffff0300, /* ps_3_0 */
5609 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5610 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5611 0x0000ffff /* end */
5613 const DWORD binormal_code[] = {
5614 0xffff0300, /* ps_3_0 */
5615 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5616 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5617 0x0000ffff /* end */
5619 /* tessfactor: fails */
5620 /* positiont: fails */
5621 const DWORD color_code[] = {
5622 0xffff0300, /* ps_3_0 */
5623 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5624 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5625 0x0000ffff /* end */
5627 const DWORD fog_code[] = {
5628 0xffff0300, /* ps_3_0 */
5629 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5630 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5631 0x0000ffff /* end */
5633 const DWORD depth_code[] = {
5634 0xffff0300, /* ps_3_0 */
5635 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5636 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5637 0x0000ffff /* end */
5639 const DWORD specular_code[] = {
5640 0xffff0300, /* ps_3_0 */
5641 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5642 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5643 0x0000ffff /* end */
5645 /* sample: fails */
5647 struct varying_test_struct tests[] = {
5648 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5649 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5650 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5651 /* Why does dx not forward the texcoord? */
5652 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5653 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5654 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5655 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5656 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5657 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5658 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5660 /* Declare a monster vertex type :-) */
5661 static const D3DVERTEXELEMENT9 decl_elements[] = {
5662 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5663 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5664 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5665 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5666 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5667 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5668 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5669 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5670 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5671 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5672 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5673 D3DDECL_END()
5675 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5676 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5677 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5678 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5679 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5680 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5681 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5682 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5683 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5684 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5685 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5686 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5687 D3DDECL_END()
5689 struct hugeVertex data[4] = {
5691 -1.0, -1.0, 0.1, 1.0,
5692 0.1, 0.1, 0.1, 0.1,
5693 0.2, 0.2, 0.2, 0.2,
5694 0.3, 0.3, 0.3, 0.3,
5695 0.4, 0.4, 0.4, 0.4,
5696 0.50, 0.55, 0.55, 0.55,
5697 0.6, 0.6, 0.6, 0.7,
5698 0.7, 0.7, 0.7, 0.6,
5699 0.8, 0.8, 0.8, 0.8,
5700 0xe6e6e6e6, /* 0.9 * 256 */
5701 0x224488ff /* Nothing special */
5704 1.0, -1.0, 0.1, 1.0,
5705 0.1, 0.1, 0.1, 0.1,
5706 0.2, 0.2, 0.2, 0.2,
5707 0.3, 0.3, 0.3, 0.3,
5708 0.4, 0.4, 0.4, 0.4,
5709 0.50, 0.55, 0.55, 0.55,
5710 0.6, 0.6, 0.6, 0.7,
5711 0.7, 0.7, 0.7, 0.6,
5712 0.8, 0.8, 0.8, 0.8,
5713 0xe6e6e6e6, /* 0.9 * 256 */
5714 0x224488ff /* Nothing special */
5717 -1.0, 1.0, 0.1, 1.0,
5718 0.1, 0.1, 0.1, 0.1,
5719 0.2, 0.2, 0.2, 0.2,
5720 0.3, 0.3, 0.3, 0.3,
5721 0.4, 0.4, 0.4, 0.4,
5722 0.50, 0.55, 0.55, 0.55,
5723 0.6, 0.6, 0.6, 0.7,
5724 0.7, 0.7, 0.7, 0.6,
5725 0.8, 0.8, 0.8, 0.8,
5726 0xe6e6e6e6, /* 0.9 * 256 */
5727 0x224488ff /* Nothing special */
5730 1.0, 1.0, 0.1, 1.0,
5731 0.1, 0.1, 0.1, 0.1,
5732 0.2, 0.2, 0.2, 0.2,
5733 0.3, 0.3, 0.3, 0.3,
5734 0.4, 0.4, 0.4, 0.4,
5735 0.50, 0.55, 0.55, 0.55,
5736 0.6, 0.6, 0.6, 0.7,
5737 0.7, 0.7, 0.7, 0.6,
5738 0.8, 0.8, 0.8, 0.8,
5739 0xe6e6e6e6, /* 0.9 * 256 */
5740 0x224488ff /* Nothing special */
5743 struct hugeVertex data2[4];
5744 IDirect3DVertexDeclaration9 *decl;
5745 IDirect3DVertexDeclaration9 *decl2;
5746 HRESULT hr;
5747 unsigned int i;
5748 DWORD color, r, g, b, r_e, g_e, b_e;
5749 BOOL drawok;
5751 memcpy(data2, data, sizeof(data2));
5752 data2[0].pos_x = 0; data2[0].pos_y = 0;
5753 data2[1].pos_x = 640; data2[1].pos_y = 0;
5754 data2[2].pos_x = 0; data2[2].pos_y = 480;
5755 data2[3].pos_x = 640; data2[3].pos_y = 480;
5757 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5758 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5759 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5760 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5761 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5762 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5764 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5766 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5767 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5768 tests[i].name, hr);
5771 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5776 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5779 hr = IDirect3DDevice9_BeginScene(device);
5780 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5781 drawok = FALSE;
5782 if(SUCCEEDED(hr))
5784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5785 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5786 drawok = SUCCEEDED(hr);
5787 hr = IDirect3DDevice9_EndScene(device);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5791 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5792 * the failure and do not check the color if it failed
5794 if(!drawok) {
5795 continue;
5798 color = getPixelColor(device, 360, 240);
5799 r = color & 0x00ff0000 >> 16;
5800 g = color & 0x0000ff00 >> 8;
5801 b = color & 0x000000ff;
5802 r_e = tests[i].color & 0x00ff0000 >> 16;
5803 g_e = tests[i].color & 0x0000ff00 >> 8;
5804 b_e = tests[i].color & 0x000000ff;
5806 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5807 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5809 if(tests[i].todo) {
5810 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5811 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5812 tests[i].name, color, tests[i].color);
5813 } else {
5814 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5815 "Test %s returned color 0x%08x, expected 0x%08x\n",
5816 tests[i].name, color, tests[i].color);
5820 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5821 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5822 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5825 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5827 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5828 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5830 hr = IDirect3DDevice9_BeginScene(device);
5831 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5832 if(SUCCEEDED(hr))
5834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5835 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5836 hr = IDirect3DDevice9_EndScene(device);
5837 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5840 color = getPixelColor(device, 360, 240);
5841 r = color & 0x00ff0000 >> 16;
5842 g = color & 0x0000ff00 >> 8;
5843 b = color & 0x000000ff;
5844 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5845 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5846 b_e = tests[i].color_rhw & 0x000000ff;
5848 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5849 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5851 if(tests[i].todo_rhw) {
5852 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5853 * pipeline
5855 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5856 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5857 tests[i].name, color, tests[i].color_rhw);
5858 } else {
5859 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5860 "Test %s returned color 0x%08x, expected 0x%08x\n",
5861 tests[i].name, color, tests[i].color_rhw);
5865 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5867 IDirect3DPixelShader9_Release(tests[i].shader);
5870 IDirect3DVertexDeclaration9_Release(decl2);
5871 IDirect3DVertexDeclaration9_Release(decl);
5874 static void test_compare_instructions(IDirect3DDevice9 *device)
5876 DWORD shader_sge_vec_code[] = {
5877 0xfffe0101, /* vs_1_1 */
5878 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5879 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5880 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5881 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5882 0x0000ffff /* end */
5884 DWORD shader_slt_vec_code[] = {
5885 0xfffe0101, /* vs_1_1 */
5886 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5887 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5888 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5889 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5890 0x0000ffff /* end */
5892 DWORD shader_sge_scalar_code[] = {
5893 0xfffe0101, /* vs_1_1 */
5894 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5895 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5896 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5897 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5898 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5899 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5900 0x0000ffff /* end */
5902 DWORD shader_slt_scalar_code[] = {
5903 0xfffe0101, /* vs_1_1 */
5904 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5905 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5906 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5907 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5908 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5909 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5910 0x0000ffff /* end */
5912 IDirect3DVertexShader9 *shader_sge_vec;
5913 IDirect3DVertexShader9 *shader_slt_vec;
5914 IDirect3DVertexShader9 *shader_sge_scalar;
5915 IDirect3DVertexShader9 *shader_slt_scalar;
5916 HRESULT hr, color;
5917 float quad1[] = {
5918 -1.0, -1.0, 0.1,
5919 0.0, -1.0, 0.1,
5920 -1.0, 0.0, 0.1,
5921 0.0, 0.0, 0.1
5923 float quad2[] = {
5924 0.0, -1.0, 0.1,
5925 1.0, -1.0, 0.1,
5926 0.0, 0.0, 0.1,
5927 1.0, 0.0, 0.1
5929 float quad3[] = {
5930 -1.0, 0.0, 0.1,
5931 0.0, 0.0, 0.1,
5932 -1.0, 1.0, 0.1,
5933 0.0, 1.0, 0.1
5935 float quad4[] = {
5936 0.0, 0.0, 0.1,
5937 1.0, 0.0, 0.1,
5938 0.0, 1.0, 0.1,
5939 1.0, 1.0, 0.1
5941 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5942 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5944 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5945 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5947 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5948 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5949 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5950 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5951 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5952 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5953 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5955 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5956 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5957 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5958 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5960 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5962 hr = IDirect3DDevice9_BeginScene(device);
5963 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5964 if(SUCCEEDED(hr))
5966 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5967 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5969 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5971 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5972 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5974 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5976 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5977 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5979 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5981 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5982 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5984 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5985 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5987 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5989 hr = IDirect3DDevice9_EndScene(device);
5990 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5993 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5994 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5996 color = getPixelColor(device, 160, 360);
5997 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5998 color = getPixelColor(device, 480, 360);
5999 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6000 color = getPixelColor(device, 160, 120);
6001 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6002 color = getPixelColor(device, 480, 160);
6003 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6006 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6008 IDirect3DVertexShader9_Release(shader_sge_vec);
6009 IDirect3DVertexShader9_Release(shader_slt_vec);
6010 IDirect3DVertexShader9_Release(shader_sge_scalar);
6011 IDirect3DVertexShader9_Release(shader_slt_scalar);
6014 static void test_vshader_input(IDirect3DDevice9 *device)
6016 DWORD swapped_shader_code_3[] = {
6017 0xfffe0300, /* vs_3_0 */
6018 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6019 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6020 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6021 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6022 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6023 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6024 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6025 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6026 0x0000ffff /* end */
6028 DWORD swapped_shader_code_1[] = {
6029 0xfffe0101, /* vs_1_1 */
6030 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6031 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6032 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6033 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6034 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6035 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6036 0x0000ffff /* end */
6038 DWORD swapped_shader_code_2[] = {
6039 0xfffe0200, /* vs_2_0 */
6040 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6041 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6042 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6043 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6044 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6045 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6046 0x0000ffff /* end */
6048 DWORD texcoord_color_shader_code_3[] = {
6049 0xfffe0300, /* vs_3_0 */
6050 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6051 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6052 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6053 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6054 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6055 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6056 0x0000ffff /* end */
6058 DWORD texcoord_color_shader_code_2[] = {
6059 0xfffe0200, /* vs_2_0 */
6060 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6061 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6062 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6063 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6064 0x0000ffff /* end */
6066 DWORD texcoord_color_shader_code_1[] = {
6067 0xfffe0101, /* vs_1_1 */
6068 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6069 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6070 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6071 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6072 0x0000ffff /* end */
6074 DWORD color_color_shader_code_3[] = {
6075 0xfffe0300, /* vs_3_0 */
6076 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6077 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6078 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6079 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6080 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6081 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6082 0x0000ffff /* end */
6084 DWORD color_color_shader_code_2[] = {
6085 0xfffe0200, /* vs_2_0 */
6086 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6087 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6088 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6089 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6090 0x0000ffff /* end */
6092 DWORD color_color_shader_code_1[] = {
6093 0xfffe0101, /* vs_1_1 */
6094 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6095 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6096 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6097 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6098 0x0000ffff /* end */
6100 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6101 HRESULT hr;
6102 DWORD color;
6103 float quad1[] = {
6104 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6105 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6106 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6107 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6109 float quad2[] = {
6110 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6111 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6112 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6113 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6115 float quad3[] = {
6116 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6117 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6118 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6119 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6121 float quad4[] = {
6122 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6123 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6124 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6125 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6127 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6128 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6129 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6130 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6131 D3DDECL_END()
6133 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6134 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6135 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6136 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6137 D3DDECL_END()
6139 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6140 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6141 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6142 D3DDECL_END()
6144 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6145 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6146 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6147 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6148 D3DDECL_END()
6150 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6151 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6152 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6153 D3DDECL_END()
6155 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6156 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6157 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6158 D3DDECL_END()
6160 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6161 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6162 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6163 D3DDECL_END()
6165 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6166 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6167 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6168 D3DDECL_END()
6170 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6171 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6172 unsigned int i;
6173 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6174 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6176 struct vertex quad1_color[] = {
6177 {-1.0, -1.0, 0.1, 0x00ff8040},
6178 { 0.0, -1.0, 0.1, 0x00ff8040},
6179 {-1.0, 0.0, 0.1, 0x00ff8040},
6180 { 0.0, 0.0, 0.1, 0x00ff8040}
6182 struct vertex quad2_color[] = {
6183 { 0.0, -1.0, 0.1, 0x00ff8040},
6184 { 1.0, -1.0, 0.1, 0x00ff8040},
6185 { 0.0, 0.0, 0.1, 0x00ff8040},
6186 { 1.0, 0.0, 0.1, 0x00ff8040}
6188 struct vertex quad3_color[] = {
6189 {-1.0, 0.0, 0.1, 0x00ff8040},
6190 { 0.0, 0.0, 0.1, 0x00ff8040},
6191 {-1.0, 1.0, 0.1, 0x00ff8040},
6192 { 0.0, 1.0, 0.1, 0x00ff8040}
6194 float quad4_color[] = {
6195 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6196 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6197 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6198 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6201 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6203 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6205 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6208 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6210 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6212 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6213 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6214 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6215 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6216 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6217 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6219 for(i = 1; i <= 3; i++) {
6220 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6221 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6222 if(i == 3) {
6223 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6225 } else if(i == 2){
6226 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6227 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6228 } else if(i == 1) {
6229 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6230 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6233 hr = IDirect3DDevice9_BeginScene(device);
6234 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6235 if(SUCCEEDED(hr))
6237 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6238 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6240 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6241 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6243 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6245 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6246 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6248 if(i == 3 || i == 2) {
6249 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6250 } else if(i == 1) {
6251 /* Succeeds or fails, depending on SW or HW vertex processing */
6252 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6255 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6258 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6260 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6261 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6263 if(i == 3 || i == 2) {
6264 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6265 } else if(i == 1) {
6266 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6269 hr = IDirect3DDevice9_EndScene(device);
6270 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6273 if(i == 3 || i == 2) {
6274 color = getPixelColor(device, 160, 360);
6275 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6276 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6278 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6279 color = getPixelColor(device, 480, 360);
6280 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6281 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6282 color = getPixelColor(device, 160, 120);
6283 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6284 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6285 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6287 color = getPixelColor(device, 480, 160);
6288 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6289 } else if(i == 1) {
6290 color = getPixelColor(device, 160, 360);
6291 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6292 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6293 color = getPixelColor(device, 480, 360);
6294 /* Accept the clear color as well in this case, since SW VP returns an error */
6295 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6296 color = getPixelColor(device, 160, 120);
6297 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6298 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6299 color = getPixelColor(device, 480, 160);
6300 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6303 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6304 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6306 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6307 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6309 /* Now find out if the whole streams are re-read, or just the last active value for the
6310 * vertices is used.
6312 hr = IDirect3DDevice9_BeginScene(device);
6313 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6314 if(SUCCEEDED(hr))
6316 float quad1_modified[] = {
6317 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6318 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6319 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6320 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6322 float quad2_modified[] = {
6323 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6324 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6325 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6326 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6329 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6330 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6332 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6333 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6335 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6337 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6338 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6339 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6340 if(i == 3 || i == 2) {
6341 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6342 } else if(i == 1) {
6343 /* Succeeds or fails, depending on SW or HW vertex processing */
6344 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6347 hr = IDirect3DDevice9_EndScene(device);
6348 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6351 color = getPixelColor(device, 480, 350);
6352 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6353 * as well.
6355 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6356 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6357 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6358 * refrast's result.
6360 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6362 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6363 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6366 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6368 IDirect3DDevice9_SetVertexShader(device, NULL);
6369 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6371 IDirect3DVertexShader9_Release(swapped_shader);
6374 for(i = 1; i <= 3; i++) {
6375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6376 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6377 if(i == 3) {
6378 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6379 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6380 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6381 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6382 } else if(i == 2){
6383 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6385 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6386 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6387 } else if(i == 1) {
6388 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6389 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6394 hr = IDirect3DDevice9_BeginScene(device);
6395 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6396 if(SUCCEEDED(hr))
6398 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6399 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6400 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6401 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6403 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6405 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6408 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6409 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6410 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6413 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6415 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6420 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6422 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6423 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6425 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6427 hr = IDirect3DDevice9_EndScene(device);
6428 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6430 IDirect3DDevice9_SetVertexShader(device, NULL);
6431 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6433 color = getPixelColor(device, 160, 360);
6434 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6435 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6436 color = getPixelColor(device, 480, 360);
6437 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6438 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6439 color = getPixelColor(device, 160, 120);
6440 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6441 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6442 color = getPixelColor(device, 480, 160);
6443 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6444 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6446 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6447 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6449 IDirect3DVertexShader9_Release(texcoord_color_shader);
6450 IDirect3DVertexShader9_Release(color_color_shader);
6453 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6454 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6455 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6456 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6458 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6459 IDirect3DVertexDeclaration9_Release(decl_color_color);
6460 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6461 IDirect3DVertexDeclaration9_Release(decl_color_float);
6464 static void srgbtexture_test(IDirect3DDevice9 *device)
6466 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6467 * texture stage state to render a quad using that texture. The resulting
6468 * color components should be 0x36 (~ 0.21), per this formula:
6469 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6470 * This is true where srgb_color > 0.04045.
6472 IDirect3D9 *d3d = NULL;
6473 HRESULT hr;
6474 LPDIRECT3DTEXTURE9 texture = NULL;
6475 LPDIRECT3DSURFACE9 surface = NULL;
6476 D3DLOCKED_RECT lr;
6477 DWORD color;
6478 float quad[] = {
6479 -1.0, 1.0, 0.0, 0.0, 0.0,
6480 1.0, 1.0, 0.0, 1.0, 0.0,
6481 -1.0, -1.0, 0.0, 0.0, 1.0,
6482 1.0, -1.0, 0.0, 1.0, 1.0,
6486 memset(&lr, 0, sizeof(lr));
6487 IDirect3DDevice9_GetDirect3D(device, &d3d);
6488 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6489 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6490 D3DFMT_A8R8G8B8) != D3D_OK) {
6491 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6492 goto out;
6495 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6496 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6497 &texture, NULL);
6498 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6499 if(!texture) {
6500 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6501 goto out;
6503 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6504 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6506 fill_surface(surface, 0xff7f7f7f);
6507 IDirect3DSurface9_Release(surface);
6509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6510 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6511 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6512 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6514 hr = IDirect3DDevice9_BeginScene(device);
6515 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6516 if(SUCCEEDED(hr))
6518 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6519 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6521 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6522 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6526 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6528 hr = IDirect3DDevice9_EndScene(device);
6529 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6532 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6533 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6534 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6535 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6537 color = getPixelColor(device, 320, 240);
6538 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6540 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6541 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6543 out:
6544 if(texture) IDirect3DTexture9_Release(texture);
6545 IDirect3D9_Release(d3d);
6548 static void shademode_test(IDirect3DDevice9 *device)
6550 /* Render a quad and try all of the different fixed function shading models. */
6551 HRESULT hr;
6552 DWORD color0, color1;
6553 DWORD color0_gouraud = 0, color1_gouraud = 0;
6554 DWORD shademode = D3DSHADE_FLAT;
6555 DWORD primtype = D3DPT_TRIANGLESTRIP;
6556 LPVOID data = NULL;
6557 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6558 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6559 UINT i, j;
6560 struct vertex quad_strip[] =
6562 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6563 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6564 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6565 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6567 struct vertex quad_list[] =
6569 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6570 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6571 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6573 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6574 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6575 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6578 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6579 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6580 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6581 if (FAILED(hr)) goto bail;
6583 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6584 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6585 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6586 if (FAILED(hr)) goto bail;
6588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6589 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6591 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6594 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6595 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6596 memcpy(data, quad_strip, sizeof(quad_strip));
6597 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6598 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6600 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6601 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6602 memcpy(data, quad_list, sizeof(quad_list));
6603 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6604 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6606 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6607 * the color fixups we have to do for FLAT shading will be dependent on that. */
6608 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6611 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6612 for (j=0; j<2; j++) {
6614 /* Inner loop just changes the D3DRS_SHADEMODE */
6615 for (i=0; i<3; i++) {
6616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6622 hr = IDirect3DDevice9_BeginScene(device);
6623 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6624 if(SUCCEEDED(hr))
6626 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6627 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6629 hr = IDirect3DDevice9_EndScene(device);
6630 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6633 /* Sample two spots from the output */
6634 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6635 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6636 switch(shademode) {
6637 case D3DSHADE_FLAT:
6638 /* Should take the color of the first vertex of each triangle */
6639 if (0)
6641 /* This test depends on EXT_provoking_vertex being
6642 * available. This extension is currently (20090810)
6643 * not common enough to let the test fail if it isn't
6644 * present. */
6645 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6646 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6648 shademode = D3DSHADE_GOURAUD;
6649 break;
6650 case D3DSHADE_GOURAUD:
6651 /* Should be an interpolated blend */
6653 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6654 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6655 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6656 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6658 color0_gouraud = color0;
6659 color1_gouraud = color1;
6661 shademode = D3DSHADE_PHONG;
6662 break;
6663 case D3DSHADE_PHONG:
6664 /* Should be the same as GOURAUD, since no hardware implements this */
6665 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6666 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6667 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6668 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6670 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6671 color0_gouraud, color0);
6672 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6673 color1_gouraud, color1);
6674 break;
6678 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6679 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6681 /* Now, do it all over again with a TRIANGLELIST */
6682 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6683 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6684 primtype = D3DPT_TRIANGLELIST;
6685 shademode = D3DSHADE_FLAT;
6688 bail:
6689 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6690 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6692 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6694 if (vb_strip)
6695 IDirect3DVertexBuffer9_Release(vb_strip);
6696 if (vb_list)
6697 IDirect3DVertexBuffer9_Release(vb_list);
6700 static void alpha_test(IDirect3DDevice9 *device)
6702 HRESULT hr;
6703 IDirect3DTexture9 *offscreenTexture;
6704 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6705 DWORD color;
6707 struct vertex quad1[] =
6709 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6710 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6711 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6712 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6714 struct vertex quad2[] =
6716 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6717 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6718 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6719 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6721 static const float composite_quad[][5] = {
6722 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6723 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6724 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6725 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6728 /* Clear the render target with alpha = 0.5 */
6729 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6730 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6732 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6733 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6735 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6736 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6737 if(!backbuffer) {
6738 goto out;
6741 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6742 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6743 if(!offscreen) {
6744 goto out;
6747 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6748 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6750 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6751 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6752 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6753 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6754 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6755 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6757 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6759 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6762 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6763 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6765 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6767 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6769 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6771 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6774 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6775 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6776 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6778 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6780 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6781 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6782 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6783 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6784 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6785 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6786 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6789 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6791 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6793 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6796 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6797 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6798 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6800 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6802 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6803 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6805 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6806 * Disable alpha blending for the final composition
6808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6809 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6810 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6811 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6813 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6814 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6816 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6817 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6818 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6820 hr = IDirect3DDevice9_EndScene(device);
6821 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6824 color = getPixelColor(device, 160, 360);
6825 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6826 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6828 color = getPixelColor(device, 160, 120);
6829 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6830 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6832 color = getPixelColor(device, 480, 360);
6833 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6834 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6836 color = getPixelColor(device, 480, 120);
6837 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6838 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6840 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6842 out:
6843 /* restore things */
6844 if(backbuffer) {
6845 IDirect3DSurface9_Release(backbuffer);
6847 if(offscreenTexture) {
6848 IDirect3DTexture9_Release(offscreenTexture);
6850 if(offscreen) {
6851 IDirect3DSurface9_Release(offscreen);
6855 struct vertex_shortcolor {
6856 float x, y, z;
6857 unsigned short r, g, b, a;
6859 struct vertex_floatcolor {
6860 float x, y, z;
6861 float r, g, b, a;
6864 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6866 HRESULT hr;
6867 BOOL s_ok, ub_ok, f_ok;
6868 DWORD color, size, i;
6869 void *data;
6870 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6871 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6872 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6873 D3DDECL_END()
6875 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6876 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6877 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6878 D3DDECL_END()
6880 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6881 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6882 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6883 D3DDECL_END()
6885 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6886 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6887 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6888 D3DDECL_END()
6890 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6891 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6892 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6893 D3DDECL_END()
6895 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6896 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6897 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6898 D3DDECL_END()
6900 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6901 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6902 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6903 D3DDECL_END()
6905 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6906 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6907 IDirect3DVertexBuffer9 *vb, *vb2;
6908 struct vertex quad1[] = /* D3DCOLOR */
6910 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6911 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6912 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6913 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6915 struct vertex quad2[] = /* UBYTE4N */
6917 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6918 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6919 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6920 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6922 struct vertex_shortcolor quad3[] = /* short */
6924 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6925 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6926 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6927 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6929 struct vertex_floatcolor quad4[] =
6931 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6932 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6933 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6934 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6936 DWORD colors[] = {
6937 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6938 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6939 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6940 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6941 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6942 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6943 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6944 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6945 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6946 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6947 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6948 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6949 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6950 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6951 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6952 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6954 float quads[] = {
6955 -1.0, -1.0, 0.1,
6956 -1.0, 0.0, 0.1,
6957 0.0, -1.0, 0.1,
6958 0.0, 0.0, 0.1,
6960 0.0, -1.0, 0.1,
6961 0.0, 0.0, 0.1,
6962 1.0, -1.0, 0.1,
6963 1.0, 0.0, 0.1,
6965 0.0, 0.0, 0.1,
6966 0.0, 1.0, 0.1,
6967 1.0, 0.0, 0.1,
6968 1.0, 1.0, 0.1,
6970 -1.0, 0.0, 0.1,
6971 -1.0, 1.0, 0.1,
6972 0.0, 0.0, 0.1,
6973 0.0, 1.0, 0.1
6975 struct tvertex quad_transformed[] = {
6976 { 90, 110, 0.1, 2.0, 0x00ffff00},
6977 { 570, 110, 0.1, 2.0, 0x00ffff00},
6978 { 90, 300, 0.1, 2.0, 0x00ffff00},
6979 { 570, 300, 0.1, 2.0, 0x00ffff00}
6981 D3DCAPS9 caps;
6983 memset(&caps, 0, sizeof(caps));
6984 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6985 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6987 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6988 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6990 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6991 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6992 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6993 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6994 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6995 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6996 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6997 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6998 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6999 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7000 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7001 } else {
7002 trace("D3DDTCAPS_UBYTE4N not supported\n");
7003 dcl_ubyte_2 = NULL;
7004 dcl_ubyte = NULL;
7006 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7007 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7008 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7009 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7011 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7012 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7013 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7014 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7016 hr = IDirect3DDevice9_BeginScene(device);
7017 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7018 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7019 if(SUCCEEDED(hr)) {
7020 if(dcl_color) {
7021 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7022 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7024 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7027 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7028 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7029 * using software vertex processing. Doh!
7031 if(dcl_ubyte) {
7032 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7033 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7035 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7036 ub_ok = SUCCEEDED(hr);
7039 if(dcl_short) {
7040 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7041 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7043 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7044 s_ok = SUCCEEDED(hr);
7047 if(dcl_float) {
7048 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7051 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7052 f_ok = SUCCEEDED(hr);
7055 hr = IDirect3DDevice9_EndScene(device);
7056 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7059 if(dcl_short) {
7060 color = getPixelColor(device, 480, 360);
7061 ok(color == 0x000000ff || !s_ok,
7062 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7064 if(dcl_ubyte) {
7065 color = getPixelColor(device, 160, 120);
7066 ok(color == 0x0000ffff || !ub_ok,
7067 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7069 if(dcl_color) {
7070 color = getPixelColor(device, 160, 360);
7071 ok(color == 0x00ffff00,
7072 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7074 if(dcl_float) {
7075 color = getPixelColor(device, 480, 120);
7076 ok(color == 0x00ff0000 || !f_ok,
7077 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7079 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7081 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7082 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7083 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7084 * whether the immediate mode code works
7086 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7087 hr = IDirect3DDevice9_BeginScene(device);
7088 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7089 if(SUCCEEDED(hr)) {
7090 if(dcl_color) {
7091 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7092 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7093 memcpy(data, quad1, sizeof(quad1));
7094 hr = IDirect3DVertexBuffer9_Unlock(vb);
7095 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7096 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7098 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7099 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7100 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7101 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7104 if(dcl_ubyte) {
7105 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7106 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7107 memcpy(data, quad2, sizeof(quad2));
7108 hr = IDirect3DVertexBuffer9_Unlock(vb);
7109 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7110 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7112 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7113 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7114 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7115 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7116 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7117 ub_ok = SUCCEEDED(hr);
7120 if(dcl_short) {
7121 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7122 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7123 memcpy(data, quad3, sizeof(quad3));
7124 hr = IDirect3DVertexBuffer9_Unlock(vb);
7125 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7126 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7127 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7128 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7129 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7130 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7131 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7132 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7133 s_ok = SUCCEEDED(hr);
7136 if(dcl_float) {
7137 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7138 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7139 memcpy(data, quad4, sizeof(quad4));
7140 hr = IDirect3DVertexBuffer9_Unlock(vb);
7141 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7142 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7143 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7144 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7145 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7146 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7147 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7148 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7149 f_ok = SUCCEEDED(hr);
7152 hr = IDirect3DDevice9_EndScene(device);
7153 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7156 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7157 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7158 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7161 if(dcl_short) {
7162 color = getPixelColor(device, 480, 360);
7163 ok(color == 0x000000ff || !s_ok,
7164 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7166 if(dcl_ubyte) {
7167 color = getPixelColor(device, 160, 120);
7168 ok(color == 0x0000ffff || !ub_ok,
7169 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7171 if(dcl_color) {
7172 color = getPixelColor(device, 160, 360);
7173 ok(color == 0x00ffff00,
7174 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7176 if(dcl_float) {
7177 color = getPixelColor(device, 480, 120);
7178 ok(color == 0x00ff0000 || !f_ok,
7179 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7181 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7184 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7186 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7187 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7188 memcpy(data, quad_transformed, sizeof(quad_transformed));
7189 hr = IDirect3DVertexBuffer9_Unlock(vb);
7190 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7192 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7193 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7195 hr = IDirect3DDevice9_BeginScene(device);
7196 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7197 if(SUCCEEDED(hr)) {
7198 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7199 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7200 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7201 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7203 hr = IDirect3DDevice9_EndScene(device);
7204 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7207 color = getPixelColor(device, 88, 108);
7208 ok(color == 0x000000ff,
7209 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7210 color = getPixelColor(device, 92, 108);
7211 ok(color == 0x000000ff,
7212 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7213 color = getPixelColor(device, 88, 112);
7214 ok(color == 0x000000ff,
7215 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7216 color = getPixelColor(device, 92, 112);
7217 ok(color == 0x00ffff00,
7218 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7220 color = getPixelColor(device, 568, 108);
7221 ok(color == 0x000000ff,
7222 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7223 color = getPixelColor(device, 572, 108);
7224 ok(color == 0x000000ff,
7225 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7226 color = getPixelColor(device, 568, 112);
7227 ok(color == 0x00ffff00,
7228 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7229 color = getPixelColor(device, 572, 112);
7230 ok(color == 0x000000ff,
7231 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7233 color = getPixelColor(device, 88, 298);
7234 ok(color == 0x000000ff,
7235 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7236 color = getPixelColor(device, 92, 298);
7237 ok(color == 0x00ffff00,
7238 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7239 color = getPixelColor(device, 88, 302);
7240 ok(color == 0x000000ff,
7241 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7242 color = getPixelColor(device, 92, 302);
7243 ok(color == 0x000000ff,
7244 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7246 color = getPixelColor(device, 568, 298);
7247 ok(color == 0x00ffff00,
7248 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7249 color = getPixelColor(device, 572, 298);
7250 ok(color == 0x000000ff,
7251 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7252 color = getPixelColor(device, 568, 302);
7253 ok(color == 0x000000ff,
7254 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7255 color = getPixelColor(device, 572, 302);
7256 ok(color == 0x000000ff,
7257 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7259 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7261 /* This test is pointless without those two declarations: */
7262 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7263 skip("color-ubyte switching test declarations aren't supported\n");
7264 goto out;
7267 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7268 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7269 memcpy(data, quads, sizeof(quads));
7270 hr = IDirect3DVertexBuffer9_Unlock(vb);
7271 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7272 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7273 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7274 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7275 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7276 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7277 memcpy(data, colors, sizeof(colors));
7278 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7279 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7281 for(i = 0; i < 2; i++) {
7282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7283 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7285 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7286 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7287 if(i == 0) {
7288 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7289 } else {
7290 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7292 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7294 hr = IDirect3DDevice9_BeginScene(device);
7295 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7296 ub_ok = FALSE;
7297 if(SUCCEEDED(hr)) {
7298 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7299 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7300 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7301 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7302 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7303 ub_ok = SUCCEEDED(hr);
7305 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7308 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7310 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7312 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7313 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7314 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7315 ub_ok = (SUCCEEDED(hr) && ub_ok);
7317 hr = IDirect3DDevice9_EndScene(device);
7318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7321 if(i == 0) {
7322 color = getPixelColor(device, 480, 360);
7323 ok(color == 0x00ff0000,
7324 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7325 color = getPixelColor(device, 160, 120);
7326 ok(color == 0x00ffffff,
7327 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7328 color = getPixelColor(device, 160, 360);
7329 ok(color == 0x000000ff || !ub_ok,
7330 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7331 color = getPixelColor(device, 480, 120);
7332 ok(color == 0x000000ff || !ub_ok,
7333 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7334 } else {
7335 color = getPixelColor(device, 480, 360);
7336 ok(color == 0x000000ff,
7337 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7338 color = getPixelColor(device, 160, 120);
7339 ok(color == 0x00ffffff,
7340 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7341 color = getPixelColor(device, 160, 360);
7342 ok(color == 0x00ff0000 || !ub_ok,
7343 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7344 color = getPixelColor(device, 480, 120);
7345 ok(color == 0x00ff0000 || !ub_ok,
7346 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7348 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7351 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7353 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7354 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7355 IDirect3DVertexBuffer9_Release(vb2);
7357 out:
7358 IDirect3DVertexBuffer9_Release(vb);
7359 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7360 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7361 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7362 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7363 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7364 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7365 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7368 struct vertex_float16color {
7369 float x, y, z;
7370 DWORD c1, c2;
7373 static void test_vshader_float16(IDirect3DDevice9 *device)
7375 HRESULT hr;
7376 DWORD color;
7377 void *data;
7378 static const D3DVERTEXELEMENT9 decl_elements[] = {
7379 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7380 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7381 D3DDECL_END()
7383 IDirect3DVertexDeclaration9 *vdecl = NULL;
7384 IDirect3DVertexBuffer9 *buffer = NULL;
7385 IDirect3DVertexShader9 *shader;
7386 DWORD shader_code[] = {
7387 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7388 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7389 0x90e40001, 0x0000ffff
7391 struct vertex_float16color quad[] = {
7392 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7393 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7394 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7395 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7397 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7398 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7399 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7400 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7402 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7403 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7404 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7405 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7407 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7408 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7409 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7410 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7414 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7416 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7417 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7418 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7419 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7420 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7421 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7423 hr = IDirect3DDevice9_BeginScene(device);
7424 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7425 if(SUCCEEDED(hr)) {
7426 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7427 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7429 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7431 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7433 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7435 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7437 hr = IDirect3DDevice9_EndScene(device);
7438 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7440 color = getPixelColor(device, 480, 360);
7441 ok(color == 0x00ff0000,
7442 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7443 color = getPixelColor(device, 160, 120);
7444 ok(color == 0x00000000,
7445 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7446 color = getPixelColor(device, 160, 360);
7447 ok(color == 0x0000ff00,
7448 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7449 color = getPixelColor(device, 480, 120);
7450 ok(color == 0x000000ff,
7451 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7452 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7454 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7455 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7457 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7458 D3DPOOL_MANAGED, &buffer, NULL);
7459 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7460 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7461 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7462 memcpy(data, quad, sizeof(quad));
7463 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7464 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7465 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7466 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7468 hr = IDirect3DDevice9_BeginScene(device);
7469 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7470 if(SUCCEEDED(hr)) {
7471 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7472 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7473 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7474 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7475 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7476 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7477 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7478 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7480 hr = IDirect3DDevice9_EndScene(device);
7481 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7484 color = getPixelColor(device, 480, 360);
7485 ok(color == 0x00ff0000,
7486 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7487 color = getPixelColor(device, 160, 120);
7488 ok(color == 0x00000000,
7489 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7490 color = getPixelColor(device, 160, 360);
7491 ok(color == 0x0000ff00,
7492 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7493 color = getPixelColor(device, 480, 120);
7494 ok(color == 0x000000ff,
7495 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7496 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7498 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7499 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7500 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7501 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7502 IDirect3DDevice9_SetVertexShader(device, NULL);
7503 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7505 IDirect3DVertexDeclaration9_Release(vdecl);
7506 IDirect3DVertexShader9_Release(shader);
7507 IDirect3DVertexBuffer9_Release(buffer);
7510 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7512 D3DCAPS9 caps;
7513 IDirect3DTexture9 *texture;
7514 HRESULT hr;
7515 D3DLOCKED_RECT rect;
7516 unsigned int x, y;
7517 DWORD *dst, color;
7518 const float quad[] = {
7519 -1.0, -1.0, 0.1, -0.2, -0.2,
7520 1.0, -1.0, 0.1, 1.2, -0.2,
7521 -1.0, 1.0, 0.1, -0.2, 1.2,
7522 1.0, 1.0, 0.1, 1.2, 1.2
7524 memset(&caps, 0, sizeof(caps));
7526 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7527 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7528 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7529 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7530 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7531 "Card has conditional NP2 support without power of two restriction set\n");
7532 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7533 return;
7534 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7535 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7536 return;
7539 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7540 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7542 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7543 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7545 memset(&rect, 0, sizeof(rect));
7546 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7547 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7548 for(y = 0; y < 10; y++) {
7549 for(x = 0; x < 10; x++) {
7550 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7551 if(x == 0 || x == 9 || y == 0 || y == 9) {
7552 *dst = 0x00ff0000;
7553 } else {
7554 *dst = 0x000000ff;
7558 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7559 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7561 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7562 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7563 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7564 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7565 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7566 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7567 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7568 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7570 hr = IDirect3DDevice9_BeginScene(device);
7571 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7572 if(SUCCEEDED(hr)) {
7573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7574 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7576 hr = IDirect3DDevice9_EndScene(device);
7577 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7580 color = getPixelColor(device, 1, 1);
7581 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7582 color = getPixelColor(device, 639, 479);
7583 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7585 color = getPixelColor(device, 135, 101);
7586 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7587 color = getPixelColor(device, 140, 101);
7588 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7589 color = getPixelColor(device, 135, 105);
7590 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7591 color = getPixelColor(device, 140, 105);
7592 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7594 color = getPixelColor(device, 135, 376);
7595 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7596 color = getPixelColor(device, 140, 376);
7597 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7598 color = getPixelColor(device, 135, 379);
7599 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7600 color = getPixelColor(device, 140, 379);
7601 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7603 color = getPixelColor(device, 500, 101);
7604 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7605 color = getPixelColor(device, 504, 101);
7606 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7607 color = getPixelColor(device, 500, 105);
7608 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7609 color = getPixelColor(device, 504, 105);
7610 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7612 color = getPixelColor(device, 500, 376);
7613 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7614 color = getPixelColor(device, 504, 376);
7615 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7616 color = getPixelColor(device, 500, 380);
7617 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7618 color = getPixelColor(device, 504, 380);
7619 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7621 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7623 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7624 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7625 IDirect3DTexture9_Release(texture);
7628 static void vFace_register_test(IDirect3DDevice9 *device)
7630 HRESULT hr;
7631 DWORD color;
7632 const DWORD shader_code[] = {
7633 0xffff0300, /* ps_3_0 */
7634 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7635 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7636 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7637 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7638 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7639 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7640 0x0000ffff /* END */
7642 const DWORD vshader_code[] = {
7643 0xfffe0300, /* vs_3_0 */
7644 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7645 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7646 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7647 0x0000ffff /* end */
7649 IDirect3DPixelShader9 *shader;
7650 IDirect3DVertexShader9 *vshader;
7651 IDirect3DTexture9 *texture;
7652 IDirect3DSurface9 *surface, *backbuffer;
7653 const float quad[] = {
7654 -1.0, -1.0, 0.1,
7655 1.0, -1.0, 0.1,
7656 -1.0, 0.0, 0.1,
7658 1.0, -1.0, 0.1,
7659 1.0, 0.0, 0.1,
7660 -1.0, 0.0, 0.1,
7662 -1.0, 0.0, 0.1,
7663 -1.0, 1.0, 0.1,
7664 1.0, 0.0, 0.1,
7666 1.0, 0.0, 0.1,
7667 -1.0, 1.0, 0.1,
7668 1.0, 1.0, 0.1,
7670 const float blit[] = {
7671 0.0, -1.0, 0.1, 0.0, 0.0,
7672 1.0, -1.0, 0.1, 1.0, 0.0,
7673 0.0, 1.0, 0.1, 0.0, 1.0,
7674 1.0, 1.0, 0.1, 1.0, 1.0,
7677 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7679 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7680 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7681 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7682 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7683 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7684 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7685 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7686 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7687 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7688 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7689 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7690 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7691 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7692 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7695 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7697 hr = IDirect3DDevice9_BeginScene(device);
7698 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7699 if(SUCCEEDED(hr)) {
7700 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7701 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7702 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7704 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7705 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7706 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7707 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7708 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7710 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7712 /* Blit the texture onto the back buffer to make it visible */
7713 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7714 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7715 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7716 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7717 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7718 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7720 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7722 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7723 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7724 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7727 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7729 hr = IDirect3DDevice9_EndScene(device);
7730 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7733 color = getPixelColor(device, 160, 360);
7734 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7735 color = getPixelColor(device, 160, 120);
7736 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7737 color = getPixelColor(device, 480, 360);
7738 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7739 color = getPixelColor(device, 480, 120);
7740 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7741 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7743 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7744 IDirect3DDevice9_SetTexture(device, 0, NULL);
7745 IDirect3DPixelShader9_Release(shader);
7746 IDirect3DVertexShader9_Release(vshader);
7747 IDirect3DSurface9_Release(surface);
7748 IDirect3DSurface9_Release(backbuffer);
7749 IDirect3DTexture9_Release(texture);
7752 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7754 HRESULT hr;
7755 DWORD color;
7756 int i;
7757 D3DCAPS9 caps;
7758 BOOL L6V5U5_supported = FALSE;
7759 IDirect3DTexture9 *tex1, *tex2;
7760 D3DLOCKED_RECT locked_rect;
7762 static const float quad[][7] = {
7763 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7764 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7765 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7766 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7769 static const D3DVERTEXELEMENT9 decl_elements[] = {
7770 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7771 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7772 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7773 D3DDECL_END()
7776 /* use asymmetric matrix to test loading */
7777 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7778 float scale, offset;
7780 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7781 IDirect3DTexture9 *texture = NULL;
7783 memset(&caps, 0, sizeof(caps));
7784 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7785 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7786 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7787 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7788 return;
7789 } else {
7790 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7791 * They report that it is not supported, but after that bump mapping works properly. So just test
7792 * if the format is generally supported, and check the BUMPENVMAP flag
7794 IDirect3D9 *d3d9;
7796 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7797 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7798 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7799 L6V5U5_supported = SUCCEEDED(hr);
7800 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7801 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7802 IDirect3D9_Release(d3d9);
7803 if(FAILED(hr)) {
7804 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7805 return;
7809 /* Generate the textures */
7810 generate_bumpmap_textures(device);
7812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7813 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7815 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7816 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7817 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7818 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7819 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7821 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7822 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7823 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7824 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7825 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7826 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7828 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7829 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7830 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7831 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7832 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7833 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7835 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7836 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7838 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7839 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7841 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7842 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7845 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7846 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7847 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7848 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7850 hr = IDirect3DDevice9_BeginScene(device);
7851 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7853 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7854 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7856 hr = IDirect3DDevice9_EndScene(device);
7857 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7859 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7860 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7861 * But since testing the color match is not the purpose of the test don't be too picky
7863 color = getPixelColor(device, 320-32, 240);
7864 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7865 color = getPixelColor(device, 320+32, 240);
7866 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7867 color = getPixelColor(device, 320, 240-32);
7868 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7869 color = getPixelColor(device, 320, 240+32);
7870 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7871 color = getPixelColor(device, 320, 240);
7872 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7873 color = getPixelColor(device, 320+32, 240+32);
7874 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7875 color = getPixelColor(device, 320-32, 240+32);
7876 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7877 color = getPixelColor(device, 320+32, 240-32);
7878 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7879 color = getPixelColor(device, 320-32, 240-32);
7880 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7882 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7884 for(i = 0; i < 2; i++) {
7885 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7886 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7887 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7888 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7889 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7890 IDirect3DTexture9_Release(texture); /* To destroy it */
7893 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7894 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7895 goto cleanup;
7897 if(L6V5U5_supported == FALSE) {
7898 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7899 goto cleanup;
7902 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7904 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7905 * would only make this test more complicated
7907 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7909 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7910 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7912 memset(&locked_rect, 0, sizeof(locked_rect));
7913 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7914 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7915 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7916 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7917 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7919 memset(&locked_rect, 0, sizeof(locked_rect));
7920 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7921 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7922 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7923 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7924 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7926 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7927 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7928 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7929 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7931 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7932 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933 scale = 2.0;
7934 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7935 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7936 offset = 0.1;
7937 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7938 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7940 hr = IDirect3DDevice9_BeginScene(device);
7941 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7942 if(SUCCEEDED(hr)) {
7943 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7944 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7945 hr = IDirect3DDevice9_EndScene(device);
7946 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7949 color = getPixelColor(device, 320, 240);
7950 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7951 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7952 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7954 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7955 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7958 /* Check a result scale factor > 1.0 */
7959 scale = 10;
7960 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7961 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7962 offset = 10;
7963 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7964 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7966 hr = IDirect3DDevice9_BeginScene(device);
7967 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7968 if(SUCCEEDED(hr)) {
7969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7970 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7971 hr = IDirect3DDevice9_EndScene(device);
7972 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7974 color = getPixelColor(device, 320, 240);
7975 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7977 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7979 /* Check clamping in the scale factor calculation */
7980 scale = 1000;
7981 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7982 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7983 offset = -1;
7984 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7985 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7987 hr = IDirect3DDevice9_BeginScene(device);
7988 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7989 if(SUCCEEDED(hr)) {
7990 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7991 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7992 hr = IDirect3DDevice9_EndScene(device);
7993 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7995 color = getPixelColor(device, 320, 240);
7996 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7997 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7998 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8000 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8001 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8002 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8003 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8005 IDirect3DTexture9_Release(tex1);
8006 IDirect3DTexture9_Release(tex2);
8008 cleanup:
8009 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8010 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8011 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8012 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8014 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8015 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8016 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8019 static void stencil_cull_test(IDirect3DDevice9 *device) {
8020 HRESULT hr;
8021 IDirect3DSurface9 *depthstencil = NULL;
8022 D3DSURFACE_DESC desc;
8023 float quad1[] = {
8024 -1.0, -1.0, 0.1,
8025 0.0, -1.0, 0.1,
8026 -1.0, 0.0, 0.1,
8027 0.0, 0.0, 0.1,
8029 float quad2[] = {
8030 0.0, -1.0, 0.1,
8031 1.0, -1.0, 0.1,
8032 0.0, 0.0, 0.1,
8033 1.0, 0.0, 0.1,
8035 float quad3[] = {
8036 0.0, 0.0, 0.1,
8037 1.0, 0.0, 0.1,
8038 0.0, 1.0, 0.1,
8039 1.0, 1.0, 0.1,
8041 float quad4[] = {
8042 -1.0, 0.0, 0.1,
8043 0.0, 0.0, 0.1,
8044 -1.0, 1.0, 0.1,
8045 0.0, 1.0, 0.1,
8047 struct vertex painter[] = {
8048 {-1.0, -1.0, 0.0, 0x00000000},
8049 { 1.0, -1.0, 0.0, 0x00000000},
8050 {-1.0, 1.0, 0.0, 0x00000000},
8051 { 1.0, 1.0, 0.0, 0x00000000},
8053 WORD indices_cw[] = {0, 1, 3};
8054 WORD indices_ccw[] = {0, 2, 3};
8055 unsigned int i;
8056 DWORD color;
8058 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8059 if(depthstencil == NULL) {
8060 skip("No depth stencil buffer\n");
8061 return;
8063 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8064 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8065 IDirect3DSurface9_Release(depthstencil);
8066 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8067 skip("No 4 or 8 bit stencil surface\n");
8068 return;
8071 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8072 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8073 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8080 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8082 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8085 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8089 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8092 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8094 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8096 /* First pass: Fill the stencil buffer with some values... */
8097 hr = IDirect3DDevice9_BeginScene(device);
8098 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8099 if(SUCCEEDED(hr))
8101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8104 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8105 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8106 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8107 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8108 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8113 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8115 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8116 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8117 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8118 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8119 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8122 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8124 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8125 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8126 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8127 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8128 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8132 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8133 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8134 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8135 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8136 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8137 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8139 hr = IDirect3DDevice9_EndScene(device);
8140 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8147 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8149 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8153 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8157 /* 2nd pass: Make the stencil values visible */
8158 hr = IDirect3DDevice9_BeginScene(device);
8159 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8160 if(SUCCEEDED(hr))
8162 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8163 for(i = 0; i < 16; i++) {
8164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8165 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8167 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8168 painter[1].diffuse = (i * 16);
8169 painter[2].diffuse = (i * 16);
8170 painter[3].diffuse = (i * 16);
8171 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8172 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8174 hr = IDirect3DDevice9_EndScene(device);
8175 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8179 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8181 color = getPixelColor(device, 160, 420);
8182 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8183 color = getPixelColor(device, 160, 300);
8184 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8186 color = getPixelColor(device, 480, 420);
8187 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8188 color = getPixelColor(device, 480, 300);
8189 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8191 color = getPixelColor(device, 160, 180);
8192 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8193 color = getPixelColor(device, 160, 60);
8194 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8196 color = getPixelColor(device, 480, 180);
8197 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8198 color = getPixelColor(device, 480, 60);
8199 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8201 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8205 static void vpos_register_test(IDirect3DDevice9 *device)
8207 HRESULT hr;
8208 DWORD color;
8209 const DWORD shader_code[] = {
8210 0xffff0300, /* ps_3_0 */
8211 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8212 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8213 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8214 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8215 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8216 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8217 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8218 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8219 0x0000ffff /* end */
8221 const DWORD shader_frac_code[] = {
8222 0xffff0300, /* ps_3_0 */
8223 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8224 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8225 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8226 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8227 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8228 0x0000ffff /* end */
8230 const DWORD vshader_code[] = {
8231 0xfffe0300, /* vs_3_0 */
8232 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8233 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8234 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8235 0x0000ffff /* end */
8237 IDirect3DVertexShader9 *vshader;
8238 IDirect3DPixelShader9 *shader, *shader_frac;
8239 IDirect3DSurface9 *surface = NULL, *backbuffer;
8240 const float quad[] = {
8241 -1.0, -1.0, 0.1, 0.0, 0.0,
8242 1.0, -1.0, 0.1, 1.0, 0.0,
8243 -1.0, 1.0, 0.1, 0.0, 1.0,
8244 1.0, 1.0, 0.1, 1.0, 1.0,
8246 D3DLOCKED_RECT lr;
8247 float constant[4] = {1.0, 0.0, 320, 240};
8248 DWORD *pos;
8250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8251 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8252 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8253 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8254 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8255 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8256 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8257 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8258 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8259 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8260 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8262 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8264 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8265 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8267 hr = IDirect3DDevice9_BeginScene(device);
8268 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8269 if(SUCCEEDED(hr)) {
8270 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8271 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8273 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8274 hr = IDirect3DDevice9_EndScene(device);
8275 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8278 /* This has to be pixel exact */
8279 color = getPixelColor(device, 319, 239);
8280 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8281 color = getPixelColor(device, 320, 239);
8282 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8283 color = getPixelColor(device, 319, 240);
8284 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8285 color = getPixelColor(device, 320, 240);
8286 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8287 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8289 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8290 &surface, NULL);
8291 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8292 hr = IDirect3DDevice9_BeginScene(device);
8293 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8294 if(SUCCEEDED(hr)) {
8295 constant[2] = 16; constant[3] = 16;
8296 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8297 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8298 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8301 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8302 hr = IDirect3DDevice9_EndScene(device);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8305 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8306 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8308 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8309 color = *pos & 0x00ffffff;
8310 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8311 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8312 color = *pos & 0x00ffffff;
8313 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8314 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8315 color = *pos & 0x00ffffff;
8316 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8317 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8318 color = *pos & 0x00ffffff;
8319 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8321 hr = IDirect3DSurface9_UnlockRect(surface);
8322 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8324 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8325 * have full control over the multisampling setting inside this test
8327 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8328 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8329 hr = IDirect3DDevice9_BeginScene(device);
8330 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8331 if(SUCCEEDED(hr)) {
8332 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8333 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8335 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8336 hr = IDirect3DDevice9_EndScene(device);
8337 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8339 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8342 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8343 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8345 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8346 color = *pos & 0x00ffffff;
8347 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8349 hr = IDirect3DSurface9_UnlockRect(surface);
8350 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8352 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8353 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8354 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8355 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8356 IDirect3DPixelShader9_Release(shader);
8357 IDirect3DPixelShader9_Release(shader_frac);
8358 IDirect3DVertexShader9_Release(vshader);
8359 if(surface) IDirect3DSurface9_Release(surface);
8360 IDirect3DSurface9_Release(backbuffer);
8363 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8365 D3DCOLOR color;
8367 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8368 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8369 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8370 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8371 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8373 ++r;
8374 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8375 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8376 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8377 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8378 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8380 return TRUE;
8383 static void pointsize_test(IDirect3DDevice9 *device)
8385 HRESULT hr;
8386 D3DCAPS9 caps;
8387 D3DMATRIX matrix;
8388 D3DMATRIX identity;
8389 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8390 DWORD color;
8391 IDirect3DSurface9 *rt, *backbuffer;
8392 IDirect3DTexture9 *tex1, *tex2;
8393 RECT rect = {0, 0, 128, 128};
8394 D3DLOCKED_RECT lr;
8395 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8396 0x00000000, 0x00000000};
8397 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8398 0x00000000, 0x0000ff00};
8400 const float vertices[] = {
8401 64, 64, 0.1,
8402 128, 64, 0.1,
8403 192, 64, 0.1,
8404 256, 64, 0.1,
8405 320, 64, 0.1,
8406 384, 64, 0.1,
8407 448, 64, 0.1,
8408 512, 64, 0.1,
8411 /* 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 */
8412 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;
8413 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;
8414 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;
8415 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;
8417 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;
8418 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;
8419 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;
8420 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;
8422 memset(&caps, 0, sizeof(caps));
8423 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8424 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8425 if(caps.MaxPointSize < 32.0) {
8426 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8427 return;
8430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8431 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8434 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8435 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8436 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8437 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8439 hr = IDirect3DDevice9_BeginScene(device);
8440 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8441 if (SUCCEEDED(hr))
8443 ptsize = 15.0;
8444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8447 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8449 ptsize = 31.0;
8450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8451 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8453 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8455 ptsize = 30.75;
8456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8457 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8459 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8461 if (caps.MaxPointSize >= 63.0)
8463 ptsize = 63.0;
8464 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8465 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8469 ptsize = 62.75;
8470 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8471 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8473 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8476 ptsize = 1.0;
8477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8478 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8480 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8482 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8483 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8484 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8485 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8487 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8488 ptsize = 15.0;
8489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8490 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8491 ptsize = 1.0;
8492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8493 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8495 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8498 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8500 /* pointsize < pointsize_min < pointsize_max?
8501 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8502 ptsize = 1.0;
8503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8505 ptsize = 15.0;
8506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8509 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8512 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8514 hr = IDirect3DDevice9_EndScene(device);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8518 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8519 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8520 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8522 if (caps.MaxPointSize >= 63.0)
8524 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8525 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8528 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8529 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8530 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8531 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8532 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8534 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8536 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8537 * generates texture coordinates for the point(result: Yes, it does)
8539 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8540 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8541 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8544 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8546 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8547 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8548 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8550 memset(&lr, 0, sizeof(lr));
8551 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8552 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8553 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8554 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8555 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8556 memset(&lr, 0, sizeof(lr));
8557 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8558 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8559 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8560 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8561 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8562 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8563 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8564 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8565 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8566 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8567 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8568 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8569 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8570 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8571 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8572 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8574 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8578 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8579 ptsize = 32.0;
8580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8581 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8583 hr = IDirect3DDevice9_BeginScene(device);
8584 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8585 if(SUCCEEDED(hr))
8587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8588 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8589 hr = IDirect3DDevice9_EndScene(device);
8590 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8593 color = getPixelColor(device, 64-4, 64-4);
8594 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8595 color = getPixelColor(device, 64-4, 64+4);
8596 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8597 color = getPixelColor(device, 64+4, 64+4);
8598 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8599 color = getPixelColor(device, 64+4, 64-4);
8600 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8601 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8603 U(matrix).m[0][0] = 1.0f / 64.0f;
8604 U(matrix).m[1][1] = -1.0f / 64.0f;
8605 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8606 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8608 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8609 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8611 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8612 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8613 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8615 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8616 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8618 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8620 hr = IDirect3DDevice9_BeginScene(device);
8621 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8623 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8624 hr = IDirect3DDevice9_EndScene(device);
8625 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8627 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8628 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8629 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8630 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8631 IDirect3DSurface9_Release(backbuffer);
8632 IDirect3DSurface9_Release(rt);
8634 color = getPixelColor(device, 64-4, 64-4);
8635 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8636 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8637 color = getPixelColor(device, 64+4, 64-4);
8638 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8639 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8640 color = getPixelColor(device, 64-4, 64+4);
8641 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8642 "Expected color 0x00000000, got 0x%08x.\n", color);
8643 color = getPixelColor(device, 64+4, 64+4);
8644 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8645 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8648 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8650 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8651 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8652 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8653 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8654 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8655 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8656 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8657 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8658 IDirect3DTexture9_Release(tex1);
8659 IDirect3DTexture9_Release(tex2);
8661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8662 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8665 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8666 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8669 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8671 static const DWORD vshader_code[] =
8673 0xfffe0300, /* vs_3_0 */
8674 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8675 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8676 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8677 0x0000ffff /* end */
8679 static const DWORD pshader_code[] =
8681 0xffff0300, /* ps_3_0 */
8682 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8683 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8684 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8685 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8686 0x0000ffff /* end */
8689 HRESULT hr;
8690 IDirect3DVertexShader9 *vs;
8691 IDirect3DPixelShader9 *ps;
8692 IDirect3DTexture9 *tex1, *tex2;
8693 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8694 D3DCAPS9 caps;
8695 DWORD color;
8696 float quad[] = {
8697 -1.0, -1.0, 0.1,
8698 1.0, -1.0, 0.1,
8699 -1.0, 1.0, 0.1,
8700 1.0, 1.0, 0.1,
8702 float texquad[] = {
8703 -1.0, -1.0, 0.1, 0.0, 0.0,
8704 0.0, -1.0, 0.1, 1.0, 0.0,
8705 -1.0, 1.0, 0.1, 0.0, 1.0,
8706 0.0, 1.0, 0.1, 1.0, 1.0,
8708 0.0, -1.0, 0.1, 0.0, 0.0,
8709 1.0, -1.0, 0.1, 1.0, 0.0,
8710 0.0, 1.0, 0.1, 0.0, 1.0,
8711 1.0, 1.0, 0.1, 1.0, 1.0,
8714 memset(&caps, 0, sizeof(caps));
8715 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8716 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8717 if(caps.NumSimultaneousRTs < 2) {
8718 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8719 return;
8722 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8723 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8725 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8726 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8727 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8729 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8730 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8731 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8732 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8733 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8734 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8735 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8736 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8737 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8738 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8740 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8741 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8742 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8743 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8744 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8745 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8747 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8748 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8749 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8750 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8751 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8752 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8753 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8754 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8755 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8756 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8759 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8760 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8761 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8762 color = getPixelColorFromSurface(readback, 8, 8);
8763 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8764 "Expected color 0x000000ff, got 0x%08x.\n", color);
8765 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8766 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8767 color = getPixelColorFromSurface(readback, 8, 8);
8768 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8769 "Expected color 0x000000ff, got 0x%08x.\n", color);
8771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8772 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8773 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8774 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8775 color = getPixelColorFromSurface(readback, 8, 8);
8776 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8777 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8778 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8779 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8780 color = getPixelColorFromSurface(readback, 8, 8);
8781 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8782 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8784 hr = IDirect3DDevice9_BeginScene(device);
8785 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8786 if(SUCCEEDED(hr)) {
8787 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8788 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8790 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8791 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8792 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8793 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8794 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8795 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8796 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8797 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8798 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8799 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8801 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8802 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8804 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8806 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8807 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8809 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8811 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8812 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8814 hr = IDirect3DDevice9_EndScene(device);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8818 color = getPixelColor(device, 160, 240);
8819 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8820 color = getPixelColor(device, 480, 240);
8821 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8822 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8824 IDirect3DPixelShader9_Release(ps);
8825 IDirect3DVertexShader9_Release(vs);
8826 IDirect3DTexture9_Release(tex1);
8827 IDirect3DTexture9_Release(tex2);
8828 IDirect3DSurface9_Release(surf1);
8829 IDirect3DSurface9_Release(surf2);
8830 IDirect3DSurface9_Release(backbuf);
8831 IDirect3DSurface9_Release(readback);
8834 struct formats {
8835 const char *fmtName;
8836 D3DFORMAT textureFormat;
8837 DWORD resultColorBlending;
8838 DWORD resultColorNoBlending;
8841 static const struct formats test_formats[] = {
8842 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8843 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8844 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8845 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8846 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8847 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8848 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8849 { NULL, 0 }
8852 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8854 HRESULT hr;
8855 IDirect3DTexture9 *offscreenTexture = NULL;
8856 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8857 IDirect3D9 *d3d = NULL;
8858 DWORD color;
8859 DWORD r0, g0, b0, r1, g1, b1;
8860 int fmt_index;
8862 static const float quad[][5] = {
8863 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8864 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8865 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8866 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8869 /* Quad with R=0x10, G=0x20 */
8870 static const struct vertex quad1[] = {
8871 {-1.0f, -1.0f, 0.1f, 0x80102000},
8872 {-1.0f, 1.0f, 0.1f, 0x80102000},
8873 { 1.0f, -1.0f, 0.1f, 0x80102000},
8874 { 1.0f, 1.0f, 0.1f, 0x80102000},
8877 /* Quad with R=0x20, G=0x10 */
8878 static const struct vertex quad2[] = {
8879 {-1.0f, -1.0f, 0.1f, 0x80201000},
8880 {-1.0f, 1.0f, 0.1f, 0x80201000},
8881 { 1.0f, -1.0f, 0.1f, 0x80201000},
8882 { 1.0f, 1.0f, 0.1f, 0x80201000},
8885 IDirect3DDevice9_GetDirect3D(device, &d3d);
8887 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8888 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8889 if(!backbuffer) {
8890 goto out;
8893 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8895 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8896 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8897 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8898 continue;
8901 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8902 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8904 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8905 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8906 if(!offscreenTexture) {
8907 continue;
8910 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8911 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8912 if(!offscreen) {
8913 continue;
8916 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8917 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8919 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8920 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8922 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8923 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8924 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8925 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8926 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8930 /* Below we will draw two quads with different colors and try to blend them together.
8931 * The result color is compared with the expected outcome.
8933 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8935 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8937 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8940 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8942 /* Draw a quad using color 0x0010200 */
8943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8944 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8946 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8948 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8950 /* Draw a quad using color 0x0020100 */
8951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8952 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8953 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8954 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8956 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8958 /* We don't want to blend the result on the backbuffer */
8959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8962 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8963 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8964 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8965 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8966 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8968 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8969 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8971 /* This time with the texture */
8972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8973 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8975 IDirect3DDevice9_EndScene(device);
8978 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8979 /* Compare the color of the center quad with our expectation */
8980 color = getPixelColor(device, 320, 240);
8981 r0 = (color & 0x00ff0000) >> 16;
8982 g0 = (color & 0x0000ff00) >> 8;
8983 b0 = (color & 0x000000ff) >> 0;
8985 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8986 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8987 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8989 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8990 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8991 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8992 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8993 } else {
8994 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8995 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8996 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8997 color = getPixelColor(device, 320, 240);
8998 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);
9000 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9002 IDirect3DDevice9_SetTexture(device, 0, NULL);
9003 if(offscreenTexture) {
9004 IDirect3DTexture9_Release(offscreenTexture);
9006 if(offscreen) {
9007 IDirect3DSurface9_Release(offscreen);
9011 out:
9012 /* restore things */
9013 if(backbuffer) {
9014 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9015 IDirect3DSurface9_Release(backbuffer);
9019 static void tssargtemp_test(IDirect3DDevice9 *device)
9021 HRESULT hr;
9022 DWORD color;
9023 static const struct vertex quad[] = {
9024 {-1.0, -1.0, 0.1, 0x00ff0000},
9025 { 1.0, -1.0, 0.1, 0x00ff0000},
9026 {-1.0, 1.0, 0.1, 0x00ff0000},
9027 { 1.0, 1.0, 0.1, 0x00ff0000}
9029 D3DCAPS9 caps;
9031 memset(&caps, 0, sizeof(caps));
9032 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9033 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9034 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9035 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9036 return;
9039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9042 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9043 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9045 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9047 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9048 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9049 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9050 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9051 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9052 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9054 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9055 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9057 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9058 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9059 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9061 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9062 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9065 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9066 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9067 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9069 hr = IDirect3DDevice9_BeginScene(device);
9070 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9071 if(SUCCEEDED(hr)) {
9072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9073 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9074 hr = IDirect3DDevice9_EndScene(device);
9075 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9077 color = getPixelColor(device, 320, 240);
9078 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9079 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9081 /* Set stage 1 back to default */
9082 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9083 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9084 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9085 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9086 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9087 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9088 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9089 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9090 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9091 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9094 struct testdata
9096 DWORD idxVertex; /* number of instances in the first stream */
9097 DWORD idxColor; /* number of instances in the second stream */
9098 DWORD idxInstance; /* should be 1 ?? */
9099 DWORD color1; /* color 1 instance */
9100 DWORD color2; /* color 2 instance */
9101 DWORD color3; /* color 3 instance */
9102 DWORD color4; /* color 4 instance */
9103 WORD strVertex; /* specify which stream to use 0-2*/
9104 WORD strColor;
9105 WORD strInstance;
9108 static const struct testdata testcases[]=
9110 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9111 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9112 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9113 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9114 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
9115 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9116 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9117 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9118 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
9119 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
9120 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9121 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9122 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9123 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9124 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9126 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9127 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9131 /* Drawing Indexed Geometry with instances*/
9132 static void stream_test(IDirect3DDevice9 *device)
9134 IDirect3DVertexBuffer9 *vb = NULL;
9135 IDirect3DVertexBuffer9 *vb2 = NULL;
9136 IDirect3DVertexBuffer9 *vb3 = NULL;
9137 IDirect3DIndexBuffer9 *ib = NULL;
9138 IDirect3DVertexDeclaration9 *pDecl = NULL;
9139 IDirect3DVertexShader9 *shader = NULL;
9140 HRESULT hr;
9141 BYTE *data;
9142 DWORD color;
9143 DWORD ind;
9144 unsigned i;
9146 const DWORD shader_code[] =
9148 0xfffe0101, /* vs_1_1 */
9149 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9150 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9151 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9152 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9153 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9154 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9155 0x0000ffff
9158 const float quad[][3] =
9160 {-0.5f, -0.5f, 1.1f}, /*0 */
9161 {-0.5f, 0.5f, 1.1f}, /*1 */
9162 { 0.5f, -0.5f, 1.1f}, /*2 */
9163 { 0.5f, 0.5f, 1.1f}, /*3 */
9166 const float vertcolor[][4] =
9168 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9169 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9170 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9171 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9174 /* 4 position for 4 instances */
9175 const float instancepos[][3] =
9177 {-0.6f,-0.6f, 0.0f},
9178 { 0.6f,-0.6f, 0.0f},
9179 { 0.6f, 0.6f, 0.0f},
9180 {-0.6f, 0.6f, 0.0f},
9183 short indices[] = {0, 1, 2, 1, 2, 3};
9185 D3DVERTEXELEMENT9 decl[] =
9187 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9188 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9189 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9190 D3DDECL_END()
9193 /* set the default value because it isn't done in wine? */
9194 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9195 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9197 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9198 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9199 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9201 /* check wrong cases */
9202 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9203 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9204 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9205 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9206 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9207 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9208 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9209 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9210 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9211 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9212 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9213 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9214 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9215 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9216 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9217 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9218 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9219 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9220 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9221 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9223 /* set the default value back */
9224 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9225 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9227 /* create all VertexBuffers*/
9228 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9229 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9230 if(!vb) {
9231 skip("Failed to create a vertex buffer\n");
9232 return;
9234 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9235 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9236 if(!vb2) {
9237 skip("Failed to create a vertex buffer\n");
9238 goto out;
9240 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9241 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9242 if(!vb3) {
9243 skip("Failed to create a vertex buffer\n");
9244 goto out;
9247 /* create IndexBuffer*/
9248 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9249 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9250 if(!ib) {
9251 skip("Failed to create a index buffer\n");
9252 goto out;
9255 /* copy all Buffers (Vertex + Index)*/
9256 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9257 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9258 memcpy(data, quad, sizeof(quad));
9259 hr = IDirect3DVertexBuffer9_Unlock(vb);
9260 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9261 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9262 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9263 memcpy(data, vertcolor, sizeof(vertcolor));
9264 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9265 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9266 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9267 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9268 memcpy(data, instancepos, sizeof(instancepos));
9269 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9270 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9271 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9272 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9273 memcpy(data, indices, sizeof(indices));
9274 hr = IDirect3DIndexBuffer9_Unlock(ib);
9275 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9277 /* create VertexShader */
9278 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9279 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9280 if(!shader) {
9281 skip("Failed to create a vetex shader\n");
9282 goto out;
9285 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9286 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9288 hr = IDirect3DDevice9_SetIndices(device, ib);
9289 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9291 /* run all tests */
9292 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9294 struct testdata act = testcases[i];
9295 decl[0].Stream = act.strVertex;
9296 decl[1].Stream = act.strColor;
9297 decl[2].Stream = act.strInstance;
9298 /* create VertexDeclarations */
9299 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9300 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9303 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9305 hr = IDirect3DDevice9_BeginScene(device);
9306 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9307 if(SUCCEEDED(hr))
9309 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9310 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9312 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9313 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9314 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9315 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9317 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9318 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9319 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9320 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9322 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9323 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9324 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9325 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9327 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9329 hr = IDirect3DDevice9_EndScene(device);
9330 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9332 /* set all StreamSource && StreamSourceFreq back to default */
9333 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9334 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9335 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9336 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9337 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9338 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9339 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9340 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9341 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9342 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9343 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9344 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9347 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9348 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9350 color = getPixelColor(device, 160, 360);
9351 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9352 color = getPixelColor(device, 480, 360);
9353 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9354 color = getPixelColor(device, 480, 120);
9355 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9356 color = getPixelColor(device, 160, 120);
9357 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9360 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9363 hr = IDirect3DDevice9_SetIndices(device, NULL);
9364 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9366 out:
9367 if(vb) IDirect3DVertexBuffer9_Release(vb);
9368 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9369 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9370 if(ib)IDirect3DIndexBuffer9_Release(ib);
9371 if(shader)IDirect3DVertexShader9_Release(shader);
9374 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9375 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9376 IDirect3DTexture9 *dsttex = NULL;
9377 HRESULT hr;
9378 DWORD color;
9379 D3DRECT r1 = {0, 0, 50, 50 };
9380 D3DRECT r2 = {50, 0, 100, 50 };
9381 D3DRECT r3 = {50, 50, 100, 100};
9382 D3DRECT r4 = {0, 50, 50, 100};
9383 const float quad[] = {
9384 -1.0, -1.0, 0.1, 0.0, 0.0,
9385 1.0, -1.0, 0.1, 1.0, 0.0,
9386 -1.0, 1.0, 0.1, 0.0, 1.0,
9387 1.0, 1.0, 0.1, 1.0, 1.0,
9390 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9391 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9393 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9394 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9395 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9396 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9398 if(!src || !dsttex) {
9399 skip("One or more test resources could not be created\n");
9400 goto cleanup;
9403 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9404 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9406 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9407 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9409 /* Clear the StretchRect destination for debugging */
9410 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9411 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9412 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9413 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9415 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9418 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9419 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9420 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9421 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9422 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9423 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9424 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9425 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9427 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9428 * the target -> texture GL blit path
9430 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9431 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9432 IDirect3DSurface9_Release(dst);
9434 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9435 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9437 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9438 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9439 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9440 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9441 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9442 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9443 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9444 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9446 hr = IDirect3DDevice9_BeginScene(device);
9447 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9448 if(SUCCEEDED(hr)) {
9449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9450 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9451 hr = IDirect3DDevice9_EndScene(device);
9452 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9455 color = getPixelColor(device, 160, 360);
9456 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9457 color = getPixelColor(device, 480, 360);
9458 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9459 color = getPixelColor(device, 480, 120);
9460 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9461 color = getPixelColor(device, 160, 120);
9462 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9463 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9466 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9467 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9468 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9469 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9471 cleanup:
9472 if(src) IDirect3DSurface9_Release(src);
9473 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9474 if(dsttex) IDirect3DTexture9_Release(dsttex);
9477 static void texop_test(IDirect3DDevice9 *device)
9479 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9480 IDirect3DTexture9 *texture = NULL;
9481 D3DLOCKED_RECT locked_rect;
9482 D3DCOLOR color;
9483 D3DCAPS9 caps;
9484 HRESULT hr;
9485 unsigned i;
9487 static const struct {
9488 float x, y, z;
9489 float s, t;
9490 D3DCOLOR diffuse;
9491 } quad[] = {
9492 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9493 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9494 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9495 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9498 static const D3DVERTEXELEMENT9 decl_elements[] = {
9499 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9500 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9501 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9502 D3DDECL_END()
9505 static const struct {
9506 D3DTEXTUREOP op;
9507 const char *name;
9508 DWORD caps_flag;
9509 D3DCOLOR result;
9510 } test_data[] = {
9511 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9512 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9513 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9514 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9515 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9516 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9517 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9518 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9519 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9520 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9521 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9522 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9523 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9524 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9525 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9526 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9527 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9528 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9529 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9530 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9531 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9532 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9533 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9536 memset(&caps, 0, sizeof(caps));
9537 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9538 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9540 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9541 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9542 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9543 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9545 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9546 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9547 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9548 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9549 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9550 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9551 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9552 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9553 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9555 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9556 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9557 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9558 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9559 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9560 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9562 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9563 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9566 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9568 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9570 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9572 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9573 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9575 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9577 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9579 skip("tex operation %s not supported\n", test_data[i].name);
9580 continue;
9583 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9584 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9586 hr = IDirect3DDevice9_BeginScene(device);
9587 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9590 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9592 hr = IDirect3DDevice9_EndScene(device);
9593 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9595 color = getPixelColor(device, 320, 240);
9596 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9597 test_data[i].name, color, test_data[i].result);
9599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9600 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9603 if (texture) IDirect3DTexture9_Release(texture);
9604 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9607 static void yuv_color_test(IDirect3DDevice9 *device) {
9608 HRESULT hr;
9609 IDirect3DSurface9 *surface = NULL, *target = NULL;
9610 unsigned int fmt, i;
9611 D3DFORMAT format;
9612 const char *fmt_string;
9613 D3DLOCKED_RECT lr;
9614 IDirect3D9 *d3d;
9615 HRESULT color;
9616 DWORD ref_color_left, ref_color_right;
9618 struct {
9619 DWORD in; /* The input color */
9620 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9621 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9622 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9623 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9624 } test_data[] = {
9625 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9626 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9627 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9628 * that
9630 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9631 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9632 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9633 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9634 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9635 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9636 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9637 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9638 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9639 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9640 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9641 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9642 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9643 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9645 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9646 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9647 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9648 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9651 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9652 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9653 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9654 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9656 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9657 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9659 for(fmt = 0; fmt < 2; fmt++) {
9660 if(fmt == 0) {
9661 format = D3DFMT_UYVY;
9662 fmt_string = "D3DFMT_UYVY";
9663 } else {
9664 format = D3DFMT_YUY2;
9665 fmt_string = "D3DFMT_YUY2";
9668 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9669 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9671 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9672 D3DRTYPE_SURFACE, format) != D3D_OK) {
9673 skip("%s is not supported\n", fmt_string);
9674 continue;
9677 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9678 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9679 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9681 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9682 if(fmt == 0) {
9683 ref_color_left = test_data[i].uyvy_left;
9684 ref_color_right = test_data[i].uyvy_right;
9685 } else {
9686 ref_color_left = test_data[i].yuy2_left;
9687 ref_color_right = test_data[i].yuy2_right;
9690 memset(&lr, 0, sizeof(lr));
9691 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9692 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9693 *((DWORD *) lr.pBits) = test_data[i].in;
9694 hr = IDirect3DSurface9_UnlockRect(surface);
9695 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9697 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9698 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9699 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9700 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9702 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9703 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9704 * want to add tests for the filtered pixels as well.
9706 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9707 * differently, so we need a max diff of 16
9709 color = getPixelColor(device, 40, 240);
9710 ok(color_match(color, ref_color_left, 18),
9711 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9712 test_data[i].in, color, ref_color_left, fmt_string);
9713 color = getPixelColor(device, 600, 240);
9714 ok(color_match(color, ref_color_right, 18),
9715 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9716 test_data[i].in, color, ref_color_right, fmt_string);
9717 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9718 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9720 IDirect3DSurface9_Release(surface);
9722 IDirect3DSurface9_Release(target);
9723 IDirect3D9_Release(d3d);
9726 static void texop_range_test(IDirect3DDevice9 *device)
9728 static const struct {
9729 float x, y, z;
9730 D3DCOLOR diffuse;
9731 } quad[] = {
9732 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9733 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9734 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9735 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9737 HRESULT hr;
9738 IDirect3DTexture9 *texture;
9739 D3DLOCKED_RECT locked_rect;
9740 D3DCAPS9 caps;
9741 DWORD color;
9743 /* We need ADD and SUBTRACT operations */
9744 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9745 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9746 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9747 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9748 return;
9750 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9751 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9752 return;
9755 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9756 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9757 /* Stage 1: result = diffuse(=1.0) + diffuse
9758 * stage 2: result = result - tfactor(= 0.5)
9760 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9761 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9762 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9763 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9764 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9765 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9766 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9767 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9768 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9769 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9770 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9771 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9772 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9773 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9775 hr = IDirect3DDevice9_BeginScene(device);
9776 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9778 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9779 hr = IDirect3DDevice9_EndScene(device);
9780 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9782 color = getPixelColor(device, 320, 240);
9783 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9784 color);
9785 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9786 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9788 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9789 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9790 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9791 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9792 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9793 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9794 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9795 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9796 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9798 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9799 * stage 2: result = result + diffuse(1.0)
9801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9802 ok(SUCCEEDED(hr), "SetRenderState 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);
9807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9808 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9809 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9810 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9811 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9812 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9814 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9816 hr = IDirect3DDevice9_BeginScene(device);
9817 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9819 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9820 hr = IDirect3DDevice9_EndScene(device);
9821 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9823 color = getPixelColor(device, 320, 240);
9824 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9825 color);
9826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9827 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9829 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9830 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9831 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9832 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9833 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9834 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9835 IDirect3DTexture9_Release(texture);
9838 static void alphareplicate_test(IDirect3DDevice9 *device) {
9839 struct vertex quad[] = {
9840 { -1.0, -1.0, 0.1, 0x80ff00ff },
9841 { 1.0, -1.0, 0.1, 0x80ff00ff },
9842 { -1.0, 1.0, 0.1, 0x80ff00ff },
9843 { 1.0, 1.0, 0.1, 0x80ff00ff },
9845 HRESULT hr;
9846 DWORD color;
9848 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9849 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9851 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9852 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9854 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9855 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9856 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9857 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9859 hr = IDirect3DDevice9_BeginScene(device);
9860 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9861 if(SUCCEEDED(hr)) {
9862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9863 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9864 hr = IDirect3DDevice9_EndScene(device);
9865 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9868 color = getPixelColor(device, 320, 240);
9869 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9870 color);
9871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9872 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9874 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9875 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9879 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9880 HRESULT hr;
9881 D3DCAPS9 caps;
9882 DWORD color;
9883 struct vertex quad[] = {
9884 { -1.0, -1.0, 0.1, 0x408080c0 },
9885 { 1.0, -1.0, 0.1, 0x408080c0 },
9886 { -1.0, 1.0, 0.1, 0x408080c0 },
9887 { 1.0, 1.0, 0.1, 0x408080c0 },
9890 memset(&caps, 0, sizeof(caps));
9891 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9892 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9893 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9894 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9895 return;
9898 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9899 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9901 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9902 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9904 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9905 * mov r0.a, diffuse.a
9906 * mov r0, r0.a
9908 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9909 * 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
9910 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9912 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9913 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9914 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9915 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9916 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9917 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9919 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9920 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9921 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9922 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9923 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9924 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9925 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9926 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9927 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9929 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9931 hr = IDirect3DDevice9_BeginScene(device);
9932 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9933 if(SUCCEEDED(hr)) {
9934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9935 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9936 hr = IDirect3DDevice9_EndScene(device);
9937 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9940 color = getPixelColor(device, 320, 240);
9941 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9942 color);
9943 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9944 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9946 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9947 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9948 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9949 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9950 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9954 static void zwriteenable_test(IDirect3DDevice9 *device) {
9955 HRESULT hr;
9956 DWORD color;
9957 struct vertex quad1[] = {
9958 { -1.0, -1.0, 0.1, 0x00ff0000},
9959 { -1.0, 1.0, 0.1, 0x00ff0000},
9960 { 1.0, -1.0, 0.1, 0x00ff0000},
9961 { 1.0, 1.0, 0.1, 0x00ff0000},
9963 struct vertex quad2[] = {
9964 { -1.0, -1.0, 0.9, 0x0000ff00},
9965 { -1.0, 1.0, 0.9, 0x0000ff00},
9966 { 1.0, -1.0, 0.9, 0x0000ff00},
9967 { 1.0, 1.0, 0.9, 0x0000ff00},
9970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9971 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9973 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9974 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9978 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9980 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9982 hr = IDirect3DDevice9_BeginScene(device);
9983 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9984 if(SUCCEEDED(hr)) {
9985 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9986 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9987 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9988 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9989 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9990 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9995 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9997 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9999 hr = IDirect3DDevice9_EndScene(device);
10000 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10003 color = getPixelColor(device, 320, 240);
10004 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10005 color);
10006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10007 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10010 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10013 static void alphatest_test(IDirect3DDevice9 *device) {
10014 #define ALPHATEST_PASSED 0x0000ff00
10015 #define ALPHATEST_FAILED 0x00ff0000
10016 struct {
10017 D3DCMPFUNC func;
10018 DWORD color_less;
10019 DWORD color_equal;
10020 DWORD color_greater;
10021 } testdata[] = {
10022 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10023 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10024 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10025 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10026 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10027 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10028 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10029 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10031 unsigned int i, j;
10032 HRESULT hr;
10033 DWORD color;
10034 struct vertex quad[] = {
10035 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10036 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10037 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10038 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10040 D3DCAPS9 caps;
10042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10043 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10044 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10045 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10047 for(j = 0; j < 2; j++) {
10048 if(j == 1) {
10049 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10050 * the alpha test either for performance reasons(floating point RTs) or to work
10051 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10052 * codepath for ffp and shader in this case, and the test should cover both
10054 IDirect3DPixelShader9 *ps;
10055 DWORD shader_code[] = {
10056 0xffff0101, /* ps_1_1 */
10057 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10058 0x0000ffff /* end */
10060 memset(&caps, 0, sizeof(caps));
10061 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10062 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10063 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10064 break;
10067 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10068 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10069 IDirect3DDevice9_SetPixelShader(device, ps);
10070 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10071 IDirect3DPixelShader9_Release(ps);
10074 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10078 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10079 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10081 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10082 hr = IDirect3DDevice9_BeginScene(device);
10083 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10084 if(SUCCEEDED(hr)) {
10085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10086 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10087 hr = IDirect3DDevice9_EndScene(device);
10088 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10090 color = getPixelColor(device, 320, 240);
10091 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10092 color, testdata[i].color_less, testdata[i].func);
10093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10094 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10097 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10100 hr = IDirect3DDevice9_BeginScene(device);
10101 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10102 if(SUCCEEDED(hr)) {
10103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10104 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10105 hr = IDirect3DDevice9_EndScene(device);
10106 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10108 color = getPixelColor(device, 320, 240);
10109 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10110 color, testdata[i].color_equal, testdata[i].func);
10111 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10112 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10114 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10115 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10117 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState 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);
10126 color = getPixelColor(device, 320, 240);
10127 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10128 color, testdata[i].color_greater, testdata[i].func);
10129 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10130 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10135 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10136 IDirect3DDevice9_SetPixelShader(device, NULL);
10137 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10140 static void sincos_test(IDirect3DDevice9 *device) {
10141 const DWORD sin_shader_code[] = {
10142 0xfffe0200, /* vs_2_0 */
10143 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10144 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10145 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10146 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10147 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10148 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10149 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10150 0x0000ffff /* end */
10152 const DWORD cos_shader_code[] = {
10153 0xfffe0200, /* vs_2_0 */
10154 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10155 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10156 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10157 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10158 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10159 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10160 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10161 0x0000ffff /* end */
10163 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10164 HRESULT hr;
10165 struct {
10166 float x, y, z;
10167 } data[1280];
10168 unsigned int i;
10169 float sincosc1[4] = {D3DSINCOSCONST1};
10170 float sincosc2[4] = {D3DSINCOSCONST2};
10172 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10173 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10175 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10176 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10177 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10178 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10179 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10180 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10181 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10182 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10183 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10184 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10186 /* Generate a point from -1 to 1 every 0.5 pixels */
10187 for(i = 0; i < 1280; i++) {
10188 data[i].x = (-640.0 + i) / 640.0;
10189 data[i].y = 0.0;
10190 data[i].z = 0.1;
10193 hr = IDirect3DDevice9_BeginScene(device);
10194 if(SUCCEEDED(hr)) {
10195 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10196 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10197 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10198 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10200 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10201 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10203 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10205 hr = IDirect3DDevice9_EndScene(device);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10208 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10209 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10210 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10212 IDirect3DDevice9_SetVertexShader(device, NULL);
10213 IDirect3DVertexShader9_Release(sin_shader);
10214 IDirect3DVertexShader9_Release(cos_shader);
10217 static void loop_index_test(IDirect3DDevice9 *device) {
10218 const DWORD shader_code[] = {
10219 0xfffe0200, /* vs_2_0 */
10220 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10221 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10222 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10223 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10224 0x0000001d, /* endloop */
10225 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10226 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10227 0x0000ffff /* END */
10229 IDirect3DVertexShader9 *shader;
10230 HRESULT hr;
10231 DWORD color;
10232 const float quad[] = {
10233 -1.0, -1.0, 0.1,
10234 1.0, -1.0, 0.1,
10235 -1.0, 1.0, 0.1,
10236 1.0, 1.0, 0.1
10238 const float zero[4] = {0, 0, 0, 0};
10239 const float one[4] = {1, 1, 1, 1};
10240 int i0[4] = {2, 10, -3, 0};
10241 float values[4];
10243 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10244 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10245 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10246 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10247 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10248 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10250 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10252 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10253 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10254 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10256 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10258 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10260 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10262 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10264 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10266 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10267 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10268 values[0] = 1.0;
10269 values[1] = 1.0;
10270 values[2] = 0.0;
10271 values[3] = 0.0;
10272 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10273 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10274 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10275 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10276 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10277 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10278 values[0] = -1.0;
10279 values[1] = 0.0;
10280 values[2] = 0.0;
10281 values[3] = 0.0;
10282 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10283 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10284 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10285 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10286 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10287 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10288 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10289 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10290 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10293 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10294 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10296 hr = IDirect3DDevice9_BeginScene(device);
10297 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10298 if(SUCCEEDED(hr))
10300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10301 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10302 hr = IDirect3DDevice9_EndScene(device);
10303 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10305 color = getPixelColor(device, 320, 240);
10306 ok(color_match(color, 0x0000ff00, 1),
10307 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10308 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10309 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10311 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10312 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10313 IDirect3DVertexShader9_Release(shader);
10316 static void sgn_test(IDirect3DDevice9 *device) {
10317 const DWORD shader_code[] = {
10318 0xfffe0200, /* vs_2_0 */
10319 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10320 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10321 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10322 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10323 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10324 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10325 0x0000ffff /* end */
10327 IDirect3DVertexShader9 *shader;
10328 HRESULT hr;
10329 DWORD color;
10330 const float quad[] = {
10331 -1.0, -1.0, 0.1,
10332 1.0, -1.0, 0.1,
10333 -1.0, 1.0, 0.1,
10334 1.0, 1.0, 0.1
10337 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10338 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10339 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10340 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10341 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10344 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10346 hr = IDirect3DDevice9_BeginScene(device);
10347 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10348 if(SUCCEEDED(hr))
10350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10351 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10352 hr = IDirect3DDevice9_EndScene(device);
10353 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10355 color = getPixelColor(device, 320, 240);
10356 ok(color_match(color, 0x008000ff, 1),
10357 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10359 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10361 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10362 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10363 IDirect3DVertexShader9_Release(shader);
10366 static void viewport_test(IDirect3DDevice9 *device) {
10367 HRESULT hr;
10368 DWORD color;
10369 D3DVIEWPORT9 vp, old_vp;
10370 BOOL draw_failed = TRUE;
10371 const float quad[] =
10373 -0.5, -0.5, 0.1,
10374 0.5, -0.5, 0.1,
10375 -0.5, 0.5, 0.1,
10376 0.5, 0.5, 0.1
10379 memset(&old_vp, 0, sizeof(old_vp));
10380 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10381 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10384 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10386 /* Test a viewport with Width and Height bigger than the surface dimensions
10388 * TODO: Test Width < surface.width, but X + Width > surface.width
10389 * TODO: Test Width < surface.width, what happens with the height?
10391 * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10392 * and Height fields bigger than the framebuffer. However, it later refuses
10393 * to draw.
10395 memset(&vp, 0, sizeof(vp));
10396 vp.X = 0;
10397 vp.Y = 0;
10398 vp.Width = 10000;
10399 vp.Height = 10000;
10400 vp.MinZ = 0.0;
10401 vp.MaxZ = 0.0;
10402 hr = IDirect3DDevice9_SetViewport(device, &vp);
10403 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10406 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10407 hr = IDirect3DDevice9_BeginScene(device);
10408 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10409 if(SUCCEEDED(hr))
10411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10412 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10413 draw_failed = FAILED(hr);
10414 hr = IDirect3DDevice9_EndScene(device);
10415 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10418 if(!draw_failed)
10420 color = getPixelColor(device, 158, 118);
10421 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10422 color = getPixelColor(device, 162, 118);
10423 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10424 color = getPixelColor(device, 158, 122);
10425 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10426 color = getPixelColor(device, 162, 122);
10427 ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10429 color = getPixelColor(device, 478, 358);
10430 ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10431 color = getPixelColor(device, 482, 358);
10432 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10433 color = getPixelColor(device, 478, 362);
10434 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10435 color = getPixelColor(device, 482, 362);
10436 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10439 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10442 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10443 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10446 /* This test tests depth clamping / clipping behaviour:
10447 * - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10448 * minimum/maximum z value.
10449 * - The viewport's MinZ/MaxZ is irrelevant for this.
10450 * - When D3DRS_CLIPPING is enabled depth values are clipped.
10451 * - Pretransformed vertices behave the same as regular vertices.
10453 static void depth_clamp_test(IDirect3DDevice9 *device)
10455 const struct tvertex quad1[] =
10457 { 0, 0, 5.0f, 1.0, 0xff002b7f},
10458 { 640, 0, 5.0f, 1.0, 0xff002b7f},
10459 { 0, 480, 5.0f, 1.0, 0xff002b7f},
10460 { 640, 480, 5.0f, 1.0, 0xff002b7f},
10462 const struct tvertex quad2[] =
10464 { 0, 300, 10.0f, 1.0, 0xfff9e814},
10465 { 640, 300, 10.0f, 1.0, 0xfff9e814},
10466 { 0, 360, 10.0f, 1.0, 0xfff9e814},
10467 { 640, 360, 10.0f, 1.0, 0xfff9e814},
10469 const struct vertex quad3[] =
10471 {-0.65, 0.55, 5.0f, 0xffffffff},
10472 {-0.35, 0.55, 5.0f, 0xffffffff},
10473 {-0.65, 0.15, 5.0f, 0xffffffff},
10474 {-0.35, 0.15, 5.0f, 0xffffffff},
10476 const struct vertex quad4[] =
10478 {-0.87, 0.83, 10.0f, 0xffffffff},
10479 {-0.65, 0.83, 10.0f, 0xffffffff},
10480 {-0.87, 0.55, 10.0f, 0xffffffff},
10481 {-0.65, 0.55, 10.0f, 0xffffffff},
10483 const struct vertex quad5[] =
10485 { -0.5, 0.5, 10.0f, 0xff14f914},
10486 { 0.5, 0.5, 10.0f, 0xff14f914},
10487 { -0.5, -0.5, 10.0f, 0xff14f914},
10488 { 0.5, -0.5, 10.0f, 0xff14f914},
10490 const struct tvertex quad6[] =
10492 { 0, 120, 10.0f, 1.0, 0xfff91414},
10493 { 640, 120, 10.0f, 1.0, 0xfff91414},
10494 { 0, 180, 10.0f, 1.0, 0xfff91414},
10495 { 640, 180, 10.0f, 1.0, 0xfff91414},
10498 D3DVIEWPORT9 vp;
10499 D3DCOLOR color;
10500 HRESULT hr;
10502 vp.X = 0;
10503 vp.Y = 0;
10504 vp.Width = 640;
10505 vp.Height = 480;
10506 vp.MinZ = 0.0;
10507 vp.MaxZ = 7.5;
10509 hr = IDirect3DDevice9_SetViewport(device, &vp);
10510 if(FAILED(hr))
10512 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10513 * the tests because the 7.5 is just intended to show that it doesn't have
10514 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10515 * viewport and continue.
10517 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10518 vp.MaxZ = 1.0;
10519 hr = IDirect3DDevice9_SetViewport(device, &vp);
10521 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10523 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10524 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10527 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10529 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10531 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10533 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10535 hr = IDirect3DDevice9_BeginScene(device);
10536 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10538 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10539 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10542 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10544 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10546 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10547 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10550 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10552 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10555 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10558 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10560 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10561 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10564 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10566 hr = IDirect3DDevice9_EndScene(device);
10567 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10569 color = getPixelColor(device, 75, 75);
10570 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10571 color = getPixelColor(device, 150, 150);
10572 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10573 color = getPixelColor(device, 320, 240);
10574 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10575 color = getPixelColor(device, 320, 330);
10576 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10577 color = getPixelColor(device, 320, 330);
10578 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10580 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10581 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10583 vp.MinZ = 0.0;
10584 vp.MaxZ = 1.0;
10585 hr = IDirect3DDevice9_SetViewport(device, &vp);
10586 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10589 static void depth_bounds_test(IDirect3DDevice9 *device)
10591 const struct tvertex quad1[] =
10593 { 0, 0, 0.0f, 1, 0xfff9e814},
10594 { 640, 0, 0.0f, 1, 0xfff9e814},
10595 { 0, 480, 1.0f, 1, 0xfff9e814},
10596 { 640, 480, 1.0f, 1, 0xfff9e814},
10598 const struct tvertex quad2[] =
10600 { 0, 0, 0.6f, 1, 0xff002b7f},
10601 { 640, 0, 0.6f, 1, 0xff002b7f},
10602 { 0, 480, 0.6f, 1, 0xff002b7f},
10603 { 640, 480, 0.6f, 1, 0xff002b7f},
10605 const struct tvertex quad3[] =
10607 { 0, 100, 0.6f, 1, 0xfff91414},
10608 { 640, 100, 0.6f, 1, 0xfff91414},
10609 { 0, 160, 0.6f, 1, 0xfff91414},
10610 { 640, 160, 0.6f, 1, 0xfff91414},
10613 union {
10614 DWORD d;
10615 float f;
10616 } tmpvalue;
10618 IDirect3D9 *d3d = NULL;
10619 IDirect3DSurface9 *offscreen_surface = NULL;
10620 D3DCOLOR color;
10621 HRESULT hr;
10623 IDirect3DDevice9_GetDirect3D(device, &d3d);
10624 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10625 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10626 skip("No NVDB (depth bounds test) support\n");
10627 IDirect3D9_Release(d3d);
10628 return;
10630 IDirect3D9_Release(d3d);
10632 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10633 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10634 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10635 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10638 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10640 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10641 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10643 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10645 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10647 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10650 hr = IDirect3DDevice9_BeginScene(device);
10651 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10653 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10654 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10657 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10660 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10662 tmpvalue.f = 0.625;
10663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10664 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10666 tmpvalue.f = 0.75;
10667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10668 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10671 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10673 tmpvalue.f = 0.75;
10674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10675 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10678 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10681 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10683 hr = IDirect3DDevice9_EndScene(device);
10684 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10686 color = getPixelColor(device, 150, 130);
10687 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10688 color = getPixelColor(device, 150, 200);
10689 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10690 color = getPixelColor(device, 150, 300-5);
10691 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10692 color = getPixelColor(device, 150, 300+5);
10693 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10694 color = getPixelColor(device, 150, 330);
10695 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10696 color = getPixelColor(device, 150, 360-5);
10697 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10698 color = getPixelColor(device, 150, 360+5);
10699 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10701 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10702 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10705 static void depth_buffer_test(IDirect3DDevice9 *device)
10707 static const struct vertex quad1[] =
10709 { -1.0, 1.0, 0.33f, 0xff00ff00},
10710 { 1.0, 1.0, 0.33f, 0xff00ff00},
10711 { -1.0, -1.0, 0.33f, 0xff00ff00},
10712 { 1.0, -1.0, 0.33f, 0xff00ff00},
10714 static const struct vertex quad2[] =
10716 { -1.0, 1.0, 0.50f, 0xffff00ff},
10717 { 1.0, 1.0, 0.50f, 0xffff00ff},
10718 { -1.0, -1.0, 0.50f, 0xffff00ff},
10719 { 1.0, -1.0, 0.50f, 0xffff00ff},
10721 static const struct vertex quad3[] =
10723 { -1.0, 1.0, 0.66f, 0xffff0000},
10724 { 1.0, 1.0, 0.66f, 0xffff0000},
10725 { -1.0, -1.0, 0.66f, 0xffff0000},
10726 { 1.0, -1.0, 0.66f, 0xffff0000},
10728 static const DWORD expected_colors[4][4] =
10730 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10731 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10732 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10733 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10736 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10737 unsigned int i, j;
10738 D3DVIEWPORT9 vp;
10739 D3DCOLOR color;
10740 HRESULT hr;
10742 vp.X = 0;
10743 vp.Y = 0;
10744 vp.Width = 640;
10745 vp.Height = 480;
10746 vp.MinZ = 0.0;
10747 vp.MaxZ = 1.0;
10749 hr = IDirect3DDevice9_SetViewport(device, &vp);
10750 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10753 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10755 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10757 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10759 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10760 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10761 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10763 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10764 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10765 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10766 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10767 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10768 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10769 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10770 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10771 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10772 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10773 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10775 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10776 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10778 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10780 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10781 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10782 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10783 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10785 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10786 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10788 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10790 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10791 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10792 hr = IDirect3DDevice9_BeginScene(device);
10793 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10795 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10796 hr = IDirect3DDevice9_EndScene(device);
10797 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10799 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10800 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10801 IDirect3DSurface9_Release(backbuffer);
10802 IDirect3DSurface9_Release(rt3);
10803 IDirect3DSurface9_Release(rt2);
10804 IDirect3DSurface9_Release(rt1);
10806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10807 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10809 hr = IDirect3DDevice9_BeginScene(device);
10810 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10812 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10814 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10815 hr = IDirect3DDevice9_EndScene(device);
10816 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10818 for (i = 0; i < 4; ++i)
10820 for (j = 0; j < 4; ++j)
10822 unsigned int x = 80 * ((2 * j) + 1);
10823 unsigned int y = 60 * ((2 * i) + 1);
10824 color = getPixelColor(device, x, y);
10825 ok(color_match(color, expected_colors[i][j], 0),
10826 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10831 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10834 static void intz_test(IDirect3DDevice9 *device)
10836 static const DWORD ps_code[] =
10838 0xffff0200, /* ps_2_0 */
10839 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10840 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10841 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
10842 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10843 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10844 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
10845 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
10846 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
10847 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
10848 0x0000ffff, /* end */
10850 struct
10852 float x, y, z;
10853 float s, t, p, q;
10855 quad[] =
10857 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
10858 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
10859 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
10860 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
10862 struct
10864 UINT x, y;
10865 D3DCOLOR color;
10867 expected_colors[] =
10869 {400, 60, D3DCOLOR_ARGB(0x00, 0x9f, 0xff, 0x00)},
10870 {560, 180, D3DCOLOR_ARGB(0x00, 0xdf, 0x55, 0x00)},
10871 {560, 300, D3DCOLOR_ARGB(0x00, 0xdf, 0x66, 0x00)},
10872 {400, 420, D3DCOLOR_ARGB(0x00, 0x9f, 0xb6, 0x00)},
10873 {240, 420, D3DCOLOR_ARGB(0x00, 0x60, 0x6d, 0x00)},
10874 { 80, 300, D3DCOLOR_ARGB(0x00, 0x20, 0x33, 0x00)},
10875 { 80, 180, D3DCOLOR_ARGB(0x00, 0x20, 0x55, 0x00)},
10876 {240, 60, D3DCOLOR_ARGB(0x00, 0x60, 0xff, 0x00)},
10879 IDirect3DSurface9 *original_ds, *original_rt, *rt;
10880 IDirect3DTexture9 *texture;
10881 IDirect3DPixelShader9 *ps;
10882 IDirect3DSurface9 *ds;
10883 IDirect3D9 *d3d9;
10884 D3DCAPS9 caps;
10885 HRESULT hr;
10886 UINT i;
10888 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10889 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
10890 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
10892 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
10893 return;
10896 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
10897 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
10899 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10900 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
10901 if (FAILED(hr))
10903 skip("No INTZ support, skipping INTZ test.\n");
10904 return;
10907 IDirect3D9_Release(d3d9);
10909 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
10910 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10911 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
10912 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10914 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
10915 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
10916 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
10917 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
10918 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
10919 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10920 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
10921 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
10924 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10926 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10928 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10930 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10932 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10934 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10935 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10936 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10937 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10938 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10939 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10940 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10941 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10942 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10943 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10945 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
10946 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
10947 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
10948 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10949 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10950 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10951 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10952 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10954 /* Setup the depth/stencil surface. */
10955 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10956 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10958 hr = IDirect3DDevice9_BeginScene(device);
10959 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10961 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10962 hr = IDirect3DDevice9_EndScene(device);
10963 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10965 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
10966 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10967 IDirect3DSurface9_Release(ds);
10968 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
10969 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10970 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10971 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10972 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10973 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10975 /* Read the depth values back. */
10976 hr = IDirect3DDevice9_BeginScene(device);
10977 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10979 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10980 hr = IDirect3DDevice9_EndScene(device);
10981 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10983 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
10985 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
10986 ok(color_match(color, expected_colors[i].color, 1),
10987 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
10988 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
10991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10992 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10994 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
10995 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10996 IDirect3DSurface9_Release(original_ds);
10997 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10998 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10999 IDirect3DTexture9_Release(texture);
11000 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11001 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11002 IDirect3DPixelShader9_Release(ps);
11004 IDirect3DSurface9_Release(original_rt);
11005 IDirect3DSurface9_Release(rt);
11008 static void shadow_test(IDirect3DDevice9 *device)
11010 static const DWORD ps_code[] =
11012 0xffff0200, /* ps_2_0 */
11013 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11014 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11015 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11016 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11017 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11018 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11019 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11020 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11021 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11022 0x0000ffff, /* end */
11024 struct
11026 D3DFORMAT format;
11027 const char *name;
11029 formats[] =
11031 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11032 {D3DFMT_D32, "D3DFMT_D32"},
11033 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11034 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11035 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11036 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11037 {D3DFMT_D16, "D3DFMT_D16"},
11038 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11039 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11041 struct
11043 float x, y, z;
11044 float s, t, p, q;
11046 quad[] =
11048 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11049 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11050 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11051 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11053 struct
11055 UINT x, y;
11056 D3DCOLOR color;
11058 expected_colors[] =
11060 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11061 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11062 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11063 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11064 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11065 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11066 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11067 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11070 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11071 IDirect3DPixelShader9 *ps;
11072 IDirect3D9 *d3d9;
11073 D3DCAPS9 caps;
11074 HRESULT hr;
11075 UINT i;
11077 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11078 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11079 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11081 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11082 return;
11085 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11086 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11087 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11088 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11089 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11090 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11092 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11093 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11094 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11095 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11096 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11098 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11099 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11101 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11103 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11105 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11107 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11109 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11110 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11111 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11112 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11113 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11114 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11115 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11116 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11117 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11118 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11120 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11122 D3DFORMAT format = formats[i].format;
11123 IDirect3DTexture9 *texture;
11124 IDirect3DSurface9 *ds;
11125 unsigned int j;
11127 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11128 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11129 if (FAILED(hr)) continue;
11131 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11132 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11133 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11135 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11136 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11138 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11139 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11141 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11142 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11144 IDirect3DDevice9_SetPixelShader(device, NULL);
11145 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11147 /* Setup the depth/stencil surface. */
11148 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11149 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11151 hr = IDirect3DDevice9_BeginScene(device);
11152 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11154 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11155 hr = IDirect3DDevice9_EndScene(device);
11156 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11158 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11159 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11160 IDirect3DSurface9_Release(ds);
11162 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11163 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11165 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11166 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11168 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11169 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11171 /* Do the actual shadow mapping. */
11172 hr = IDirect3DDevice9_BeginScene(device);
11173 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11175 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11176 hr = IDirect3DDevice9_EndScene(device);
11177 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11179 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11180 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11181 IDirect3DTexture9_Release(texture);
11183 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11185 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11186 ok(color_match(color, expected_colors[j].color, 0),
11187 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11188 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11189 formats[i].name, color);
11192 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11193 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11196 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11197 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11198 IDirect3DPixelShader9_Release(ps);
11200 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11201 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11202 IDirect3DSurface9_Release(original_ds);
11204 IDirect3DSurface9_Release(original_rt);
11205 IDirect3DSurface9_Release(rt);
11207 IDirect3D9_Release(d3d9);
11210 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11212 const struct vertex quad1[] =
11214 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11215 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11216 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
11217 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
11219 const struct vertex quad2[] =
11221 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11222 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11223 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
11224 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
11226 D3DCOLOR color;
11227 HRESULT hr;
11229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11230 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11232 hr = IDirect3DDevice9_BeginScene(device);
11233 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11235 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11236 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11241 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11244 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11246 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11248 hr = IDirect3DDevice9_EndScene(device);
11249 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11251 color = getPixelColor(device, 1, 240);
11252 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11253 color = getPixelColor(device, 638, 240);
11254 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11256 color = getPixelColor(device, 1, 241);
11257 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11258 color = getPixelColor(device, 638, 241);
11259 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11262 static void clip_planes_test(IDirect3DDevice9 *device)
11264 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11266 const DWORD shader_code[] = {
11267 0xfffe0200, /* vs_2_0 */
11268 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11269 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11270 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11271 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11272 0x0000ffff /* end */
11274 IDirect3DVertexShader9 *shader;
11276 IDirect3DTexture9 *offscreen = NULL;
11277 IDirect3DSurface9 *offscreen_surface, *original_rt;
11278 HRESULT hr;
11280 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11281 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11284 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11286 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11288 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11290 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11292 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11293 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11295 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11297 clip_planes(device, "Onscreen FFP");
11299 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11300 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11301 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11302 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11303 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11306 clip_planes(device, "Offscreen FFP");
11308 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11309 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11311 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11312 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11313 IDirect3DDevice9_SetVertexShader(device, shader);
11314 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11316 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11319 clip_planes(device, "Onscreen vertex shader");
11321 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11322 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11324 clip_planes(device, "Offscreen vertex shader");
11326 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11327 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11329 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11330 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11331 IDirect3DVertexShader9_Release(shader);
11332 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11334 IDirect3DSurface9_Release(original_rt);
11335 if (offscreen)
11337 IDirect3DSurface9_Release(offscreen_surface);
11338 IDirect3DTexture9_Release(offscreen);
11342 static void fp_special_test(IDirect3DDevice9 *device)
11344 static const DWORD vs_header[] =
11346 0xfffe0200, /* vs_2_0 */
11347 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11348 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11349 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11352 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11353 static const DWORD vs_pow[] =
11354 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11355 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11356 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11357 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11358 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11359 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11361 static const DWORD vs_footer[] =
11363 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11364 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11365 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11366 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11367 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11368 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11369 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11370 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11371 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11372 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11373 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11374 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11375 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11376 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11377 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11378 0x0000ffff, /* end */
11381 static const struct
11383 const char *name;
11384 const DWORD *ops;
11385 DWORD size;
11386 D3DCOLOR r600;
11387 D3DCOLOR nv40;
11388 D3DCOLOR nv50;
11390 vs_body[] =
11392 /* The basic ideas here are:
11393 * 2.0 * +/-INF == +/-INF
11394 * NAN != NAN
11396 * The vertex shader value is written to the red component, with 0.0
11397 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11398 * result in 0x00. The pixel shader value is written to the green
11399 * component, but here 0.0 also results in 0x00. The actual value is
11400 * written to the blue component.
11402 * There are considerable differences between graphics cards in how
11403 * these are handled, but pow and nrm never generate INF or NAN. */
11404 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
11405 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
11406 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
11407 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11408 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
11409 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11410 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11413 static const DWORD ps_code[] =
11415 0xffff0200, /* ps_2_0 */
11416 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11417 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11418 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11419 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11420 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11421 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11422 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11423 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11424 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11425 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11426 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11427 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11428 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11429 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11430 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11431 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11432 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11433 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11434 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11435 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11436 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11437 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11438 0x0000ffff, /* end */
11441 struct
11443 float x, y, z;
11444 float s;
11446 quad[] =
11448 { -1.0f, 1.0f, 0.0f, 0.0f},
11449 { 1.0f, 1.0f, 1.0f, 0.0f},
11450 { -1.0f, -1.0f, 0.0f, 0.0f},
11451 { 1.0f, -1.0f, 1.0f, 0.0f},
11454 IDirect3DPixelShader9 *ps;
11455 UINT body_size = 0;
11456 DWORD *vs_code;
11457 D3DCAPS9 caps;
11458 HRESULT hr;
11459 UINT i;
11461 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11462 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11463 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11465 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11466 return;
11469 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11470 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11472 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11473 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11474 IDirect3DDevice9_SetPixelShader(device, ps);
11475 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11478 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11481 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11483 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11485 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11488 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11489 memcpy(vs_code, vs_header, sizeof(vs_header));
11491 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11493 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11494 IDirect3DVertexShader9 *vs;
11495 D3DCOLOR color;
11497 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11498 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11499 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11501 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11502 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11503 IDirect3DDevice9_SetVertexShader(device, vs);
11504 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11506 hr = IDirect3DDevice9_BeginScene(device);
11507 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11509 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11510 hr = IDirect3DDevice9_EndScene(device);
11511 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11513 color = getPixelColor(device, 320, 240);
11514 ok(color_match(color, vs_body[i].r600, 1)
11515 || color_match(color, vs_body[i].nv40, 1)
11516 || color_match(color, vs_body[i].nv50, 1),
11517 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11518 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11520 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11521 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11523 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11524 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11525 IDirect3DVertexShader9_Release(vs);
11528 HeapFree(GetProcessHeap(), 0, vs_code);
11530 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11531 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11532 IDirect3DPixelShader9_Release(ps);
11535 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11537 IDirect3D9 *d3d;
11538 IDirect3DSurface9 *rt, *backbuffer;
11539 IDirect3DTexture9 *texture;
11540 HRESULT hr;
11541 int i;
11542 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11543 static const struct
11545 D3DFORMAT fmt;
11546 const char *name;
11548 formats[] =
11550 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11551 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11552 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11553 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11554 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11556 static const struct
11558 float x, y, z;
11559 float u, v;
11561 quad[] =
11563 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
11564 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
11565 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
11566 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
11569 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11570 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11571 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11572 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11573 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11574 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11575 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11576 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11578 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11580 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11582 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11583 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11585 skip("Format %s not supported as render target, skipping test.\n",
11586 formats[i].name);
11587 continue;
11590 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11591 D3DPOOL_DEFAULT, &texture, NULL);
11592 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11593 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11594 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11596 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11597 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11598 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11599 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11600 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11601 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11603 hr = IDirect3DDevice9_BeginScene(device);
11604 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11605 if(SUCCEEDED(hr))
11607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11608 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11609 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11610 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11612 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11615 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11616 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11617 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11618 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11619 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11620 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11621 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11623 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11624 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11625 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11627 hr = IDirect3DDevice9_EndScene(device);
11628 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11631 IDirect3DSurface9_Release(rt);
11632 IDirect3DTexture9_Release(texture);
11634 color = getPixelColor(device, 360, 240);
11635 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11636 D3DUSAGE_QUERY_SRGBWRITE,
11637 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11639 /* Big slop for R5G6B5 */
11640 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11641 formats[i].name, color_srgb, color);
11643 else
11645 /* Big slop for R5G6B5 */
11646 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11647 formats[i].name, color_rgb, color);
11650 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11651 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11654 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11655 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11657 IDirect3D9_Release(d3d);
11658 IDirect3DSurface9_Release(backbuffer);
11661 START_TEST(visual)
11663 IDirect3DDevice9 *device_ptr;
11664 D3DCAPS9 caps;
11665 HRESULT hr;
11666 DWORD color;
11668 d3d9_handle = LoadLibraryA("d3d9.dll");
11669 if (!d3d9_handle)
11671 skip("Could not load d3d9.dll\n");
11672 return;
11675 device_ptr = init_d3d9();
11676 if (!device_ptr)
11678 skip("Creating the device failed\n");
11679 return;
11682 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11684 /* Check for the reliability of the returned data */
11685 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11686 if(FAILED(hr))
11688 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11689 goto cleanup;
11692 color = getPixelColor(device_ptr, 1, 1);
11693 if(color !=0x00ff0000)
11695 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11696 goto cleanup;
11698 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11700 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11701 if(FAILED(hr))
11703 skip("Clear failed, can't assure correctness of the test results, skipping\n");
11704 goto cleanup;
11707 color = getPixelColor(device_ptr, 639, 479);
11708 if(color != 0x0000ddee)
11710 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11711 goto cleanup;
11713 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11715 /* Now execute the real tests */
11716 depth_clamp_test(device_ptr);
11717 stretchrect_test(device_ptr);
11718 lighting_test(device_ptr);
11719 clear_test(device_ptr);
11720 color_fill_test(device_ptr);
11721 fog_test(device_ptr);
11722 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11724 test_cube_wrap(device_ptr);
11725 } else {
11726 skip("No cube texture support\n");
11728 z_range_test(device_ptr);
11729 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11731 maxmip_test(device_ptr);
11733 else
11735 skip("No mipmap support\n");
11737 offscreen_test(device_ptr);
11738 alpha_test(device_ptr);
11739 shademode_test(device_ptr);
11740 srgbtexture_test(device_ptr);
11741 release_buffer_test(device_ptr);
11742 float_texture_test(device_ptr);
11743 g16r16_texture_test(device_ptr);
11744 pixelshader_blending_test(device_ptr);
11745 texture_transform_flags_test(device_ptr);
11746 autogen_mipmap_test(device_ptr);
11747 fixed_function_decl_test(device_ptr);
11748 conditional_np2_repeat_test(device_ptr);
11749 fixed_function_bumpmap_test(device_ptr);
11750 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11751 stencil_cull_test(device_ptr);
11752 } else {
11753 skip("No two sided stencil support\n");
11755 pointsize_test(device_ptr);
11756 tssargtemp_test(device_ptr);
11757 np2_stretch_rect_test(device_ptr);
11758 yuv_color_test(device_ptr);
11759 zwriteenable_test(device_ptr);
11760 alphatest_test(device_ptr);
11761 viewport_test(device_ptr);
11763 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11765 test_constant_clamp_vs(device_ptr);
11766 test_compare_instructions(device_ptr);
11768 else skip("No vs_1_1 support\n");
11770 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11772 test_mova(device_ptr);
11773 loop_index_test(device_ptr);
11774 sincos_test(device_ptr);
11775 sgn_test(device_ptr);
11776 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11777 test_vshader_input(device_ptr);
11778 test_vshader_float16(device_ptr);
11779 stream_test(device_ptr);
11780 } else {
11781 skip("No vs_3_0 support\n");
11784 else skip("No vs_2_0 support\n");
11786 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11788 fog_with_shader_test(device_ptr);
11790 else skip("No vs_1_1 and ps_1_1 support\n");
11792 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11794 texbem_test(device_ptr);
11795 texdepth_test(device_ptr);
11796 texkill_test(device_ptr);
11797 x8l8v8u8_test(device_ptr);
11798 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11799 constant_clamp_ps_test(device_ptr);
11800 cnd_test(device_ptr);
11801 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11802 dp2add_ps_test(device_ptr);
11803 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11804 nested_loop_test(device_ptr);
11805 fixed_function_varying_test(device_ptr);
11806 vFace_register_test(device_ptr);
11807 vpos_register_test(device_ptr);
11808 multiple_rendertargets_test(device_ptr);
11809 } else {
11810 skip("No ps_3_0 or vs_3_0 support\n");
11812 } else {
11813 skip("No ps_2_0 support\n");
11817 else skip("No ps_1_1 support\n");
11819 texop_test(device_ptr);
11820 texop_range_test(device_ptr);
11821 alphareplicate_test(device_ptr);
11822 dp3_alpha_test(device_ptr);
11823 depth_buffer_test(device_ptr);
11824 intz_test(device_ptr);
11825 shadow_test(device_ptr);
11826 fp_special_test(device_ptr);
11827 depth_bounds_test(device_ptr);
11828 srgbwrite_format_test(device_ptr);
11829 clip_planes_test(device_ptr);
11831 cleanup:
11832 if(device_ptr) {
11833 D3DPRESENT_PARAMETERS present_parameters;
11834 IDirect3DSwapChain9 *swapchain;
11835 ULONG ref;
11837 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11838 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11839 IDirect3DSwapChain9_Release(swapchain);
11840 ref = IDirect3DDevice9_Release(device_ptr);
11841 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11842 DestroyWindow(present_parameters.hDeviceWindow);