d3d9/tests: Make shader bytecode static const.
[wine/wine-gecko.git] / dlls / d3d9 / tests / visual.c
blobe84e8fdf43fd1f58561b86fa4e863e9992f9b4b4
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 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 struct vec3
39 float x, y, z;
42 struct vec4
44 float x, y, z, w;
47 static HWND create_window(void)
49 WNDCLASS wc = {0};
50 HWND ret;
51 wc.lpfnWndProc = DefWindowProc;
52 wc.lpszClassName = "d3d9_test_wc";
53 RegisterClass(&wc);
55 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
56 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
57 ShowWindow(ret, SW_SHOW);
58 return ret;
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
63 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64 c1 >>= 8; c2 >>= 8;
65 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66 c1 >>= 8; c2 >>= 8;
67 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68 c1 >>= 8; c2 >>= 8;
69 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
70 return TRUE;
73 /* Locks a given surface and returns the color at (x,y). It's the caller's
74 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
75 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
77 DWORD color;
78 HRESULT hr;
79 D3DSURFACE_DESC desc;
80 RECT rectToLock = {x, y, x+1, y+1};
81 D3DLOCKED_RECT lockedRect;
83 hr = IDirect3DSurface9_GetDesc(surface, &desc);
84 if(FAILED(hr)) /* This is not a test */
86 trace("Can't get the surface description, hr=%08x\n", hr);
87 return 0xdeadbeef;
90 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
91 if(FAILED(hr)) /* This is not a test */
93 trace("Can't lock the surface, hr=%08x\n", hr);
94 return 0xdeadbeef;
96 switch(desc.Format) {
97 case D3DFMT_A8R8G8B8:
99 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
100 break;
102 default:
103 trace("Error: unknown surface format: %d\n", desc.Format);
104 color = 0xdeadbeef;
105 break;
107 hr = IDirect3DSurface9_UnlockRect(surface);
108 if(FAILED(hr))
110 trace("Can't unlock the surface, hr=%08x\n", hr);
112 return color;
115 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
117 DWORD ret;
118 IDirect3DSurface9 *surf = NULL, *target = NULL;
119 HRESULT hr;
120 D3DLOCKED_RECT lockedRect;
121 RECT rectToLock = {x, y, x+1, y+1};
123 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
124 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
125 if (FAILED(hr) || !surf)
127 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
128 return 0xdeadbeef;
131 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
132 if(FAILED(hr))
134 trace("Can't get the render target, hr=%08x\n", hr);
135 ret = 0xdeadbeed;
136 goto out;
139 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
140 if (FAILED(hr))
142 trace("Can't read the render target data, hr=%08x\n", hr);
143 ret = 0xdeadbeec;
144 goto out;
147 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
148 if(FAILED(hr))
150 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
151 ret = 0xdeadbeeb;
152 goto out;
155 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
156 * really important for these tests
158 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
159 hr = IDirect3DSurface9_UnlockRect(surf);
160 if(FAILED(hr))
162 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
165 out:
166 if(target) IDirect3DSurface9_Release(target);
167 if(surf) IDirect3DSurface9_Release(surf);
168 return ret;
171 static IDirect3DDevice9 *init_d3d9(void)
173 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
174 IDirect3D9 *d3d9_ptr = 0;
175 IDirect3DDevice9 *device_ptr = 0;
176 D3DPRESENT_PARAMETERS present_parameters;
177 HRESULT hr;
178 D3DADAPTER_IDENTIFIER9 identifier;
180 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
181 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
182 if (!d3d9_create) return NULL;
184 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
185 if (!d3d9_ptr)
187 win_skip("could not create D3D9\n");
188 return NULL;
191 ZeroMemory(&present_parameters, sizeof(present_parameters));
192 present_parameters.Windowed = TRUE;
193 present_parameters.hDeviceWindow = create_window();
194 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
195 present_parameters.BackBufferWidth = 640;
196 present_parameters.BackBufferHeight = 480;
197 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
198 present_parameters.EnableAutoDepthStencil = TRUE;
199 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
201 memset(&identifier, 0, sizeof(identifier));
202 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
203 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
204 trace("Driver string: \"%s\"\n", identifier.Driver);
205 trace("Description string: \"%s\"\n", identifier.Description);
206 ok(identifier.Description[0] != '\0', "Empty driver description\n");
207 trace("Device name string: \"%s\"\n", identifier.DeviceName);
208 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
209 trace("Driver version %d.%d.%d.%d\n",
210 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
211 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
213 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
214 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
215 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
216 "Failed to create a device, hr %#x.\n", hr);
218 return device_ptr;
221 static void cleanup_device(IDirect3DDevice9 *device)
223 if (device)
225 D3DPRESENT_PARAMETERS present_parameters;
226 IDirect3DSwapChain9 *swapchain;
227 ULONG ref;
229 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
230 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
231 IDirect3DSwapChain9_Release(swapchain);
232 ref = IDirect3DDevice9_Release(device);
233 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
234 DestroyWindow(present_parameters.hDeviceWindow);
238 struct vertex
240 float x, y, z;
241 DWORD diffuse;
244 struct tvertex
246 float x, y, z, rhw;
247 DWORD diffuse;
250 struct nvertex
252 float x, y, z;
253 float nx, ny, nz;
254 DWORD diffuse;
257 static void lighting_test(IDirect3DDevice9 *device)
259 HRESULT hr;
260 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
261 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
262 DWORD color;
263 D3DMATERIAL9 material, old_material;
264 DWORD cop, carg;
265 DWORD old_colorwrite;
267 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
268 0.0f, 1.0f, 0.0f, 0.0f,
269 0.0f, 0.0f, 1.0f, 0.0f,
270 0.0f, 0.0f, 0.0f, 1.0f };
272 struct vertex unlitquad[] =
274 {-1.0f, -1.0f, 0.1f, 0xffff0000},
275 {-1.0f, 0.0f, 0.1f, 0xffff0000},
276 { 0.0f, 0.0f, 0.1f, 0xffff0000},
277 { 0.0f, -1.0f, 0.1f, 0xffff0000},
279 struct vertex litquad[] =
281 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
282 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
283 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
284 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
286 struct nvertex unlitnquad[] =
288 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
289 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
290 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
291 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
293 struct nvertex litnquad[] =
295 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
296 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
297 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
298 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
300 WORD Indices[] = {0, 1, 2, 2, 3, 0};
302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
305 /* Setup some states that may cause issues */
306 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
308 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
327 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
328 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
329 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
333 hr = IDirect3DDevice9_SetFVF(device, 0);
334 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
336 hr = IDirect3DDevice9_SetFVF(device, fvf);
337 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
339 hr = IDirect3DDevice9_BeginScene(device);
340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
341 if(hr == D3D_OK)
343 /* No lights are defined... That means, lit vertices should be entirely black */
344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
345 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
346 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
347 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
348 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
352 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
353 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
354 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
356 hr = IDirect3DDevice9_SetFVF(device, nfvf);
357 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
360 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
361 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
362 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
363 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
366 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
368 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
369 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
371 hr = IDirect3DDevice9_EndScene(device);
372 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
375 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
376 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
377 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
378 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
379 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
380 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
381 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
382 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
384 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
386 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
387 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
388 memset(&material, 0, sizeof(material));
389 material.Diffuse.r = 0.0;
390 material.Diffuse.g = 0.0;
391 material.Diffuse.b = 0.0;
392 material.Diffuse.a = 1.0;
393 material.Ambient.r = 0.0;
394 material.Ambient.g = 0.0;
395 material.Ambient.b = 0.0;
396 material.Ambient.a = 0.0;
397 material.Specular.r = 0.0;
398 material.Specular.g = 0.0;
399 material.Specular.b = 0.0;
400 material.Specular.a = 0.0;
401 material.Emissive.r = 0.0;
402 material.Emissive.g = 0.0;
403 material.Emissive.b = 0.0;
404 material.Emissive.a = 0.0;
405 material.Power = 0.0;
406 hr = IDirect3DDevice9_SetMaterial(device, &material);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
414 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
415 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
416 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
417 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
418 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
421 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
423 hr = IDirect3DDevice9_BeginScene(device);
424 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
425 if(SUCCEEDED(hr)) {
426 struct vertex lighting_test[] = {
427 {-1.0, -1.0, 0.1, 0x8000ff00},
428 { 1.0, -1.0, 0.1, 0x80000000},
429 {-1.0, 1.0, 0.1, 0x8000ff00},
430 { 1.0, 1.0, 0.1, 0x80000000}
432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
435 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
437 hr = IDirect3DDevice9_EndScene(device);
438 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
441 color = getPixelColor(device, 320, 240);
442 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
443 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
445 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
446 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
450 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
454 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
455 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
456 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
457 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
458 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
461 static void clear_test(IDirect3DDevice9 *device)
463 /* Tests the correctness of clearing parameters */
464 HRESULT hr;
465 D3DRECT rect[2];
466 D3DRECT rect_negneg;
467 DWORD color;
468 D3DVIEWPORT9 old_vp, vp;
469 RECT scissor;
470 DWORD oldColorWrite;
471 BOOL invalid_clear_failed = FALSE;
473 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
474 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
476 /* Positive x, negative y */
477 rect[0].x1 = 0;
478 rect[0].y1 = 480;
479 rect[0].x2 = 320;
480 rect[0].y2 = 240;
482 /* Positive x, positive y */
483 rect[1].x1 = 0;
484 rect[1].y1 = 0;
485 rect[1].x2 = 320;
486 rect[1].y2 = 240;
487 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
488 * returns D3D_OK, but ignores the rectangle silently
490 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
491 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
492 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
494 /* negative x, negative y */
495 rect_negneg.x1 = 640;
496 rect_negneg.y1 = 240;
497 rect_negneg.x2 = 320;
498 rect_negneg.y2 = 0;
499 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
500 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
503 color = getPixelColor(device, 160, 360); /* lower left quad */
504 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
505 color = getPixelColor(device, 160, 120); /* upper left quad */
506 if(invalid_clear_failed) {
507 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
508 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
509 } else {
510 /* If the negative rectangle was dropped silently, the correct ones are cleared */
511 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
513 color = getPixelColor(device, 480, 360); /* lower right quad */
514 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
515 color = getPixelColor(device, 480, 120); /* upper right quad */
516 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
518 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
520 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
521 * clear the red quad in the top left part of the render target. For some reason it
522 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
523 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
524 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
525 * pick some obvious value
527 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
528 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
530 /* Test how the viewport affects clears */
531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
532 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
533 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
534 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
536 vp.X = 160;
537 vp.Y = 120;
538 vp.Width = 160;
539 vp.Height = 120;
540 vp.MinZ = 0.0;
541 vp.MaxZ = 1.0;
542 hr = IDirect3DDevice9_SetViewport(device, &vp);
543 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
545 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
547 vp.X = 320;
548 vp.Y = 240;
549 vp.Width = 320;
550 vp.Height = 240;
551 vp.MinZ = 0.0;
552 vp.MaxZ = 1.0;
553 hr = IDirect3DDevice9_SetViewport(device, &vp);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555 rect[0].x1 = 160;
556 rect[0].y1 = 120;
557 rect[0].x2 = 480;
558 rect[0].y2 = 360;
559 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
562 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
563 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
565 color = getPixelColor(device, 158, 118);
566 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
567 color = getPixelColor(device, 162, 118);
568 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
569 color = getPixelColor(device, 158, 122);
570 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
571 color = getPixelColor(device, 162, 122);
572 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
574 color = getPixelColor(device, 318, 238);
575 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
576 color = getPixelColor(device, 322, 238);
577 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
578 color = getPixelColor(device, 318, 242);
579 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
580 color = getPixelColor(device, 322, 242);
581 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
583 color = getPixelColor(device, 478, 358);
584 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
585 color = getPixelColor(device, 482, 358);
586 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
587 color = getPixelColor(device, 478, 362);
588 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
589 color = getPixelColor(device, 482, 362);
590 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
592 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
594 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
595 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
597 scissor.left = 160;
598 scissor.right = 480;
599 scissor.top = 120;
600 scissor.bottom = 360;
601 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
602 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
604 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
607 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
608 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
609 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
612 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
614 color = getPixelColor(device, 158, 118);
615 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
616 color = getPixelColor(device, 162, 118);
617 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
618 color = getPixelColor(device, 158, 122);
619 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
620 color = getPixelColor(device, 162, 122);
621 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
623 color = getPixelColor(device, 158, 358);
624 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
625 color = getPixelColor(device, 162, 358);
626 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
627 color = getPixelColor(device, 158, 358);
628 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
629 color = getPixelColor(device, 162, 362);
630 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
632 color = getPixelColor(device, 478, 118);
633 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
634 color = getPixelColor(device, 478, 122);
635 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
636 color = getPixelColor(device, 482, 122);
637 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
638 color = getPixelColor(device, 482, 358);
639 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
641 color = getPixelColor(device, 478, 358);
642 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
643 color = getPixelColor(device, 478, 362);
644 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
645 color = getPixelColor(device, 482, 358);
646 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
647 color = getPixelColor(device, 482, 362);
648 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
650 color = getPixelColor(device, 318, 238);
651 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
652 color = getPixelColor(device, 318, 242);
653 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
654 color = getPixelColor(device, 322, 238);
655 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
656 color = getPixelColor(device, 322, 242);
657 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
659 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
661 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
662 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
666 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
667 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
668 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
674 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
676 /* Colorwriteenable does not affect the clear */
677 color = getPixelColor(device, 320, 240);
678 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
680 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
682 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
683 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
685 rect[0].x1 = 0;
686 rect[0].y1 = 0;
687 rect[0].x2 = 640;
688 rect[0].y2 = 480;
689 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
690 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
692 color = getPixelColor(device, 320, 240);
693 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
694 "Clear with count = 0, rect != NULL has color %08x\n", color);
696 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
698 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
699 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
700 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
701 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
703 color = getPixelColor(device, 320, 240);
704 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
705 "Clear with count = 1, rect = NULL has color %08x\n", color);
707 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
710 static void color_fill_test(IDirect3DDevice9 *device)
712 HRESULT hr;
713 IDirect3DSurface9 *backbuffer = NULL;
714 IDirect3DSurface9 *rt_surface = NULL;
715 IDirect3DSurface9 *offscreen_surface = NULL;
716 DWORD fill_color, color;
718 /* Test ColorFill on a the backbuffer (should pass) */
719 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
720 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
721 if(backbuffer)
723 fill_color = 0x112233;
724 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
725 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
727 color = getPixelColor(device, 0, 0);
728 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
730 IDirect3DSurface9_Release(backbuffer);
733 /* Test ColorFill on a render target surface (should pass) */
734 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
735 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
736 if(rt_surface)
738 fill_color = 0x445566;
739 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
740 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
742 color = getPixelColorFromSurface(rt_surface, 0, 0);
743 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
745 IDirect3DSurface9_Release(rt_surface);
748 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
749 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
750 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
751 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
752 if(offscreen_surface)
754 fill_color = 0x778899;
755 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
756 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
758 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
759 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
761 IDirect3DSurface9_Release(offscreen_surface);
764 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
765 offscreen_surface = NULL;
766 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
767 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
768 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
769 if(offscreen_surface)
771 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
772 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
774 IDirect3DSurface9_Release(offscreen_surface);
778 typedef struct {
779 float in[4];
780 DWORD out;
781 } test_data_t;
784 * c7 mova ARGB mov ARGB
785 * -2.4 -2 0x00ffff00 -3 0x00ff0000
786 * -1.6 -2 0x00ffff00 -2 0x00ffff00
787 * -0.4 0 0x0000ffff -1 0x0000ff00
788 * 0.4 0 0x0000ffff 0 0x0000ffff
789 * 1.6 2 0x00ff00ff 1 0x000000ff
790 * 2.4 2 0x00ff00ff 2 0x00ff00ff
792 static void test_mova(IDirect3DDevice9 *device)
794 static const DWORD mova_test[] = {
795 0xfffe0200, /* vs_2_0 */
796 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
797 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
798 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
799 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
800 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
801 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
802 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
803 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
804 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
805 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
806 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
807 0x0000ffff /* END */
809 static const DWORD mov_test[] = {
810 0xfffe0101, /* vs_1_1 */
811 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
812 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
813 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
814 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
815 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
816 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
817 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
818 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
819 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
820 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
821 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
822 0x0000ffff /* END */
825 static const test_data_t test_data[2][6] = {
827 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
828 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
829 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
830 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
831 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
832 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
835 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
836 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
837 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
838 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
839 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
840 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
844 static const float quad[][3] = {
845 {-1.0f, -1.0f, 0.0f},
846 {-1.0f, 1.0f, 0.0f},
847 { 1.0f, -1.0f, 0.0f},
848 { 1.0f, 1.0f, 0.0f},
851 static const D3DVERTEXELEMENT9 decl_elements[] = {
852 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
853 D3DDECL_END()
856 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
857 IDirect3DVertexShader9 *mova_shader = NULL;
858 IDirect3DVertexShader9 *mov_shader = NULL;
859 HRESULT hr;
860 UINT i, j;
862 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
863 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
864 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
865 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
866 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
867 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
868 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
869 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
871 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
872 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
873 for(j = 0; j < 2; ++j)
875 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
877 DWORD color;
879 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
880 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
882 hr = IDirect3DDevice9_BeginScene(device);
883 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
886 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
888 hr = IDirect3DDevice9_EndScene(device);
889 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
891 color = getPixelColor(device, 320, 240);
892 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
893 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
895 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
896 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
898 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
899 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
901 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
902 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
905 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
906 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
908 IDirect3DVertexDeclaration9_Release(vertex_declaration);
909 IDirect3DVertexShader9_Release(mova_shader);
910 IDirect3DVertexShader9_Release(mov_shader);
913 struct sVertex {
914 float x, y, z;
915 DWORD diffuse;
916 DWORD specular;
919 struct sVertexT {
920 float x, y, z, rhw;
921 DWORD diffuse;
922 DWORD specular;
925 static void fog_test(IDirect3DDevice9 *device)
927 HRESULT hr;
928 D3DCOLOR color;
929 float start = 0.0f, end = 1.0f;
930 D3DCAPS9 caps;
931 int i;
933 /* Gets full z based fog with linear fog, no fog with specular color */
934 struct sVertex untransformed_1[] = {
935 {-1, -1, 0.1f, 0xffff0000, 0xff000000 },
936 {-1, 0, 0.1f, 0xffff0000, 0xff000000 },
937 { 0, 0, 0.1f, 0xffff0000, 0xff000000 },
938 { 0, -1, 0.1f, 0xffff0000, 0xff000000 },
940 /* Ok, I am too lazy to deal with transform matrices */
941 struct sVertex untransformed_2[] = {
942 {-1, 0, 1.0f, 0xffff0000, 0xff000000 },
943 {-1, 1, 1.0f, 0xffff0000, 0xff000000 },
944 { 0, 1, 1.0f, 0xffff0000, 0xff000000 },
945 { 0, 0, 1.0f, 0xffff0000, 0xff000000 },
947 /* Untransformed ones. Give them a different diffuse color to make the test look
948 * nicer. It also makes making sure that they are drawn correctly easier.
950 struct sVertexT transformed_1[] = {
951 {320, 0, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
952 {640, 0, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
953 {640, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
954 {320, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
956 struct sVertexT transformed_2[] = {
957 {320, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
958 {640, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
959 {640, 480, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
960 {320, 480, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
962 struct vertex rev_fog_quads[] = {
963 {-1.0, -1.0, 0.1, 0x000000ff},
964 {-1.0, 0.0, 0.1, 0x000000ff},
965 { 0.0, 0.0, 0.1, 0x000000ff},
966 { 0.0, -1.0, 0.1, 0x000000ff},
968 { 0.0, -1.0, 0.9, 0x000000ff},
969 { 0.0, 0.0, 0.9, 0x000000ff},
970 { 1.0, 0.0, 0.9, 0x000000ff},
971 { 1.0, -1.0, 0.9, 0x000000ff},
973 { 0.0, 0.0, 0.4, 0x000000ff},
974 { 0.0, 1.0, 0.4, 0x000000ff},
975 { 1.0, 1.0, 0.4, 0x000000ff},
976 { 1.0, 0.0, 0.4, 0x000000ff},
978 {-1.0, 0.0, 0.7, 0x000000ff},
979 {-1.0, 1.0, 0.7, 0x000000ff},
980 { 0.0, 1.0, 0.7, 0x000000ff},
981 { 0.0, 0.0, 0.7, 0x000000ff},
983 WORD Indices[] = {0, 1, 2, 2, 3, 0};
985 const float ident_mat[16] =
987 1.0f, 0.0f, 0.0f, 0.0f,
988 0.0f, 1.0f, 0.0f, 0.0f,
989 0.0f, 0.0f, 1.0f, 0.0f,
990 0.0f, 0.0f, 0.0f, 1.0f
992 const float world_mat1[16] =
994 1.0f, 0.0f, 0.0f, 0.0f,
995 0.0f, 1.0f, 0.0f, 0.0f,
996 0.0f, 0.0f, 1.0f, 0.0f,
997 0.0f, 0.0f, -0.5f, 1.0f
999 const float world_mat2[16] =
1001 1.0f, 0.0f, 0.0f, 0.0f,
1002 0.0f, 1.0f, 0.0f, 0.0f,
1003 0.0f, 0.0f, 1.0f, 0.0f,
1004 0.0f, 0.0f, 1.0f, 1.0f
1006 const float proj_mat[16] =
1008 1.0f, 0.0f, 0.0f, 0.0f,
1009 0.0f, 1.0f, 0.0f, 0.0f,
1010 0.0f, 0.0f, 1.0f, 0.0f,
1011 0.0f, 0.0f, -1.0f, 1.0f
1014 const struct sVertex far_quad1[] =
1016 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1017 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1018 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1019 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1021 const struct sVertex far_quad2[] =
1023 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1024 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1025 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1026 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1029 memset(&caps, 0, sizeof(caps));
1030 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1031 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1035 /* Setup initial states: No lighting, fog on, fog color */
1036 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1037 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1039 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1041 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1043 /* First test: Both table fog and vertex fog off */
1044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1047 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1049 /* Start = 0, end = 1. Should be default, but set them */
1050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1051 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1053 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1055 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1058 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1059 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1060 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1061 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1062 sizeof(untransformed_1[0]));
1063 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1065 /* That makes it use the Z value */
1066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1067 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1068 /* Untransformed, vertex fog != none (or table fog != none):
1069 * Use the Z value as input into the equation
1071 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1072 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1073 sizeof(untransformed_2[0]));
1074 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1076 /* transformed verts */
1077 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1078 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1079 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1080 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1081 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1082 sizeof(transformed_1[0]));
1083 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1086 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1087 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1088 * equation
1090 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1091 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1092 sizeof(transformed_2[0]));
1093 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1095 hr = IDirect3DDevice9_EndScene(device);
1096 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1098 else
1100 ok(FALSE, "BeginScene failed\n");
1103 color = getPixelColor(device, 160, 360);
1104 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1105 color = getPixelColor(device, 160, 120);
1106 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1107 color = getPixelColor(device, 480, 120);
1108 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1109 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1111 color = getPixelColor(device, 480, 360);
1112 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1114 else
1116 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1117 * The settings above result in no fogging with vertex fog
1119 color = getPixelColor(device, 480, 120);
1120 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1121 trace("Info: Table fog not supported by this device\n");
1123 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1125 /* Now test the special case fogstart == fogend */
1126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1127 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1129 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1131 start = 512;
1132 end = 512;
1133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1134 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1136 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1139 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1141 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1143 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1145 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1146 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1147 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1148 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1149 * color and has fixed fogstart and fogend.
1151 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1152 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1153 sizeof(untransformed_1[0]));
1154 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1155 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1156 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1157 sizeof(untransformed_2[0]));
1158 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1160 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1161 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1162 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1163 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1164 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1165 sizeof(transformed_1[0]));
1166 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1168 hr = IDirect3DDevice9_EndScene(device);
1169 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1171 else
1173 ok(FALSE, "BeginScene failed\n");
1175 color = getPixelColor(device, 160, 360);
1176 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1177 color = getPixelColor(device, 160, 120);
1178 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1179 color = getPixelColor(device, 480, 120);
1180 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1181 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1183 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1184 * but without shaders it seems to work everywhere
1186 end = 0.2;
1187 start = 0.8;
1188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1189 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1190 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1191 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1192 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1193 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1195 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1196 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1197 * so skip this for now
1199 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1200 const char *mode = (i ? "table" : "vertex");
1201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1202 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1204 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1206 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1207 hr = IDirect3DDevice9_BeginScene(device);
1208 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1209 if(SUCCEEDED(hr)) {
1210 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1211 4, 5, 6, 6, 7, 4,
1212 8, 9, 10, 10, 11, 8,
1213 12, 13, 14, 14, 15, 12};
1215 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1216 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1217 sizeof(rev_fog_quads[0]));
1218 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1220 hr = IDirect3DDevice9_EndScene(device);
1221 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1223 color = getPixelColor(device, 160, 360);
1224 ok(color_match(color, 0x0000ff00, 1),
1225 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1227 color = getPixelColor(device, 160, 120);
1228 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1229 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1231 color = getPixelColor(device, 480, 120);
1232 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1233 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1235 color = getPixelColor(device, 480, 360);
1236 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1238 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1240 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1241 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1242 break;
1246 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1248 /* A simple fog + non-identity world matrix test */
1249 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1250 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1252 start = 0.0;
1253 end = 1.0;
1254 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1255 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1257 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1258 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1259 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1261 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1264 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1266 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1268 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1269 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1271 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1272 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1273 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1275 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1276 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1277 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1279 hr = IDirect3DDevice9_EndScene(device);
1280 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1282 else
1284 ok(FALSE, "BeginScene failed\n");
1287 color = getPixelColor(device, 160, 360);
1288 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1289 "Unfogged quad has color %08x\n", color);
1290 color = getPixelColor(device, 160, 120);
1291 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1292 "Fogged out quad has color %08x\n", color);
1294 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1296 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1297 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1298 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1299 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1300 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1303 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1305 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1307 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1308 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1310 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1311 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1312 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1314 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1315 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1316 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1318 hr = IDirect3DDevice9_EndScene(device);
1319 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1321 else
1323 ok(FALSE, "BeginScene failed\n");
1326 color = getPixelColor(device, 160, 360);
1327 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1328 color = getPixelColor(device, 160, 120);
1329 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1330 "Fogged out quad has color %08x\n", color);
1332 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1334 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1335 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1336 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1337 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1339 else
1341 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1344 /* Test RANGEFOG vs FOGTABLEMODE */
1345 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1346 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1348 struct sVertex untransformed_3[] =
1350 {-1.0,-1.0, 0.4999f, 0xffff0000, 0xff000000 },
1351 {-1.0, 1.0, 0.4999f, 0xffff0000, 0xff000000 },
1352 { 1.0,-1.0, 0.4999f, 0xffff0000, 0xff000000 },
1353 { 1.0, 1.0, 0.4999f, 0xffff0000, 0xff000000 },
1356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1357 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1358 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1359 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1362 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1364 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1365 * is not used, the fog coordinate will be equal to fogstart and the quad not
1366 * fogged. If range fog is used the fog coordinate will be slightly higher and
1367 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1368 * is calculated per vertex and interpolated, so even the center of the screen
1369 * where the difference doesn't matter will be fogged, but check the corners in
1370 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1371 start = 0.5f;
1372 end = 0.50001f;
1373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1374 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1376 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1378 /* Table fog: Range fog is not used */
1379 hr = IDirect3DDevice9_BeginScene(device);
1380 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1381 if (SUCCEEDED(hr))
1383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1384 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1386 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1387 hr = IDirect3DDevice9_EndScene(device);
1388 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1390 color = getPixelColor(device, 10, 10);
1391 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1392 color = getPixelColor(device, 630, 10);
1393 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1394 color = getPixelColor(device, 10, 470);
1395 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1396 color = getPixelColor(device, 630, 470);
1397 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1399 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1400 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1402 /* Vertex fog: Rangefog is used */
1403 hr = IDirect3DDevice9_BeginScene(device);
1404 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1405 if (SUCCEEDED(hr))
1407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1408 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1412 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1413 hr = IDirect3DDevice9_EndScene(device);
1414 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1416 color = getPixelColor(device, 10, 10);
1417 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1418 "Rangefog with vertex fog returned color 0x%08x\n", color);
1419 color = getPixelColor(device, 630, 10);
1420 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1421 "Rangefog with vertex fog returned color 0x%08x\n", color);
1422 color = getPixelColor(device, 10, 470);
1423 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1424 "Rangefog with vertex fog returned color 0x%08x\n", color);
1425 color = getPixelColor(device, 630, 470);
1426 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1427 "Rangefog with vertex fog returned color 0x%08x\n", color);
1429 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1430 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1433 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1435 else
1437 skip("Range fog or table fog not supported, skipping range fog tests\n");
1440 /* Turn off the fog master switch to avoid confusing other tests */
1441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1442 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1444 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1446 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1449 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1450 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1451 * regardless of the actual addressing mode set. The way this test works is
1452 * that we sample in one of the corners of the cubemap with filtering enabled,
1453 * and check the interpolated color. There are essentially two reasonable
1454 * things an implementation can do: Either pick one of the faces and
1455 * interpolate the edge texel with itself (i.e., clamp within the face), or
1456 * interpolate between the edge texels of the three involved faces. It should
1457 * never involve the border color or the other side (texcoord wrapping) of a
1458 * face in the interpolation. */
1459 static void test_cube_wrap(IDirect3DDevice9 *device)
1461 static const float quad[][6] = {
1462 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1463 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1464 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1465 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1468 static const D3DVERTEXELEMENT9 decl_elements[] = {
1469 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1470 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1471 D3DDECL_END()
1474 static const struct {
1475 D3DTEXTUREADDRESS mode;
1476 const char *name;
1477 } address_modes[] = {
1478 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1479 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1480 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1481 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1482 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1485 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1486 IDirect3DCubeTexture9 *texture = NULL;
1487 IDirect3DSurface9 *surface = NULL;
1488 IDirect3DSurface9 *face_surface;
1489 D3DLOCKED_RECT locked_rect;
1490 HRESULT hr;
1491 UINT x;
1492 INT y, face;
1494 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1495 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1496 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1497 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1499 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1500 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1501 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1503 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1504 D3DPOOL_DEFAULT, &texture, NULL);
1505 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1507 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1508 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1510 for (y = 0; y < 128; ++y)
1512 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1513 for (x = 0; x < 64; ++x)
1515 *ptr++ = 0xff0000ff;
1517 for (x = 64; x < 128; ++x)
1519 *ptr++ = 0xffff0000;
1523 hr = IDirect3DSurface9_UnlockRect(surface);
1524 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1526 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1527 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1529 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1530 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1532 IDirect3DSurface9_Release(face_surface);
1534 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1535 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1537 for (y = 0; y < 128; ++y)
1539 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1540 for (x = 0; x < 64; ++x)
1542 *ptr++ = 0xffff0000;
1544 for (x = 64; x < 128; ++x)
1546 *ptr++ = 0xff0000ff;
1550 hr = IDirect3DSurface9_UnlockRect(surface);
1551 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1553 /* Create cube faces */
1554 for (face = 1; face < 6; ++face)
1556 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1557 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1559 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1560 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1562 IDirect3DSurface9_Release(face_surface);
1565 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1566 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1568 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1569 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1570 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1571 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1572 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1573 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1578 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1580 DWORD color;
1582 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1583 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1584 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1585 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1587 hr = IDirect3DDevice9_BeginScene(device);
1588 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1590 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1591 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1593 hr = IDirect3DDevice9_EndScene(device);
1594 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1596 color = getPixelColor(device, 320, 240);
1597 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1598 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1599 color, address_modes[x].name);
1601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1602 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1604 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1605 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1608 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1609 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1611 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1612 IDirect3DCubeTexture9_Release(texture);
1613 IDirect3DSurface9_Release(surface);
1616 static void offscreen_test(IDirect3DDevice9 *device)
1618 HRESULT hr;
1619 IDirect3DTexture9 *offscreenTexture = NULL;
1620 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1621 DWORD color;
1623 static const float quad[][5] = {
1624 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1625 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1626 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1627 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1630 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1631 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1633 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1634 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1635 if(!offscreenTexture) {
1636 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1637 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1638 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1639 if(!offscreenTexture) {
1640 skip("Cannot create an offscreen render target\n");
1641 goto out;
1645 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1646 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1647 if(!backbuffer) {
1648 goto out;
1651 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1652 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1653 if(!offscreen) {
1654 goto out;
1657 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1658 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1660 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1661 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1662 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1663 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1664 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1665 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1666 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1667 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1668 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1669 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1671 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1672 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1673 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1674 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1675 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1677 /* Draw without textures - Should result in a white quad */
1678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1679 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1681 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1682 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1683 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1684 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1686 /* This time with the texture */
1687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1688 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1690 IDirect3DDevice9_EndScene(device);
1693 /* Center quad - should be white */
1694 color = getPixelColor(device, 320, 240);
1695 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1696 /* Some quad in the cleared part of the texture */
1697 color = getPixelColor(device, 170, 240);
1698 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1699 /* Part of the originally cleared back buffer */
1700 color = getPixelColor(device, 10, 10);
1701 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1702 if(0) {
1703 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1704 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1705 * the offscreen rendering mode this test would succeed or fail
1707 color = getPixelColor(device, 10, 470);
1708 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1711 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1713 out:
1714 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1715 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1717 /* restore things */
1718 if (backbuffer)
1720 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1721 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1722 IDirect3DSurface9_Release(backbuffer);
1724 if(offscreenTexture) {
1725 IDirect3DTexture9_Release(offscreenTexture);
1727 if(offscreen) {
1728 IDirect3DSurface9_Release(offscreen);
1732 /* This test tests fog in combination with shaders.
1733 * What's tested: linear fog (vertex and table) with pixel shader
1734 * linear table fog with non foggy vertex shader
1735 * vertex fog with foggy vertex shader, non-linear
1736 * fog with shader, non-linear fog with foggy shader,
1737 * linear table fog with foggy shader
1739 static void fog_with_shader_test(IDirect3DDevice9 *device)
1741 HRESULT hr;
1742 DWORD color;
1743 union {
1744 float f;
1745 DWORD i;
1746 } start, end;
1747 unsigned int i, j;
1749 /* basic vertex shader without fog computation ("non foggy") */
1750 static const DWORD vertex_shader_code1[] =
1752 0xfffe0101, /* vs_1_1 */
1753 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1754 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1755 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1756 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1757 0x0000ffff
1759 /* basic vertex shader with reversed fog computation ("foggy") */
1760 static const DWORD vertex_shader_code2[] =
1762 0xfffe0101, /* vs_1_1 */
1763 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1764 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1765 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1766 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1767 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1768 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1769 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1770 0x0000ffff
1772 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1773 static const DWORD vertex_shader_code3[] =
1775 0xfffe0200, /* vs_2_0 */
1776 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1777 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1778 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1779 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1780 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1781 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1782 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1783 0x0000ffff
1785 /* basic pixel shader */
1786 static const DWORD pixel_shader_code[] =
1788 0xffff0101, /* ps_1_1 */
1789 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1790 0x0000ffff
1792 static const DWORD pixel_shader_code2[] =
1794 0xffff0200, /* ps_2_0 */
1795 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
1796 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
1797 0x0000ffff
1800 static struct vertex quad[] = {
1801 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
1802 {-1.0f, 1.0f, 0.0f, 0xffff0000 },
1803 { 1.0f, -1.0f, 0.0f, 0xffff0000 },
1804 { 1.0f, 1.0f, 0.0f, 0xffff0000 },
1807 static const D3DVERTEXELEMENT9 decl_elements[] = {
1808 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1809 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1810 D3DDECL_END()
1813 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1814 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
1815 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
1817 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1818 static const struct test_data_t {
1819 int vshader;
1820 int pshader;
1821 D3DFOGMODE vfog;
1822 D3DFOGMODE tfog;
1823 unsigned int color[11];
1824 } test_data[] = {
1825 /* only pixel shader: */
1826 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1827 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1830 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1833 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1834 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1835 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1836 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1837 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1838 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1839 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1840 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1842 /* vertex shader */
1843 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1844 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1845 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1846 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1847 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1848 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1849 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1850 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1851 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1853 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1854 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1857 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1860 /* vertex shader and pixel shader */
1861 /* The next 4 tests would read the fog coord output, but it isn't available.
1862 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1863 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1864 * These tests should be disabled if some other hardware behaves differently
1866 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1867 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1868 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1869 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1870 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1871 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1872 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1873 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1874 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1875 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1876 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1877 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1879 /* These use the Z coordinate with linear table fog */
1880 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1881 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1882 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1883 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1884 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1885 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1886 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1887 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1888 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1889 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1890 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1891 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1893 /* Non-linear table fog without fog coord */
1894 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1895 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1896 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1897 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1898 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1899 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1901 /* These tests fail on older Nvidia drivers */
1902 /* foggy vertex shader */
1903 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1904 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1905 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1906 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1907 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1910 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1913 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1916 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1917 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1918 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1919 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1920 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1921 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1922 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1923 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1924 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1925 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1926 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1927 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1929 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1930 * all using the fixed fog-coord linear fog
1932 /* vs_1_1 with ps_1_1 */
1933 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1934 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1935 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1936 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1937 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1938 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1939 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1940 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1941 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1942 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1943 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1944 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1946 /* vs_2_0 with ps_1_1 */
1947 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1948 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1949 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1950 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1951 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1952 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1953 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1954 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1955 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1956 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1957 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1958 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1960 /* vs_1_1 with ps_2_0 */
1961 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1962 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1963 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1964 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1965 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1966 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1967 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1968 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1969 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1970 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1971 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1972 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1974 /* vs_2_0 with ps_2_0 */
1975 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1976 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1977 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1978 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1979 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1980 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1981 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1982 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1983 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1984 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1985 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1986 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1988 /* These use table fog. Here the shader-provided fog coordinate is
1989 * ignored and the z coordinate used instead
1991 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1992 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1993 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1994 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1995 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1996 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1997 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1998 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1999 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2002 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
2003 start.f=0.1f;
2004 end.f=0.9f;
2006 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2007 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2008 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2009 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2010 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2011 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2012 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2013 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2014 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2015 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2016 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2017 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2019 /* Setup initial states: No lighting, fog on, fog color */
2020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2021 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2023 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2025 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2026 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2027 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2030 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2032 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2034 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2036 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2038 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2040 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2042 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2043 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2044 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2045 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2047 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2049 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2051 for(j=0; j < 11; j++)
2053 /* Don't use the whole zrange to prevent rounding errors */
2054 quad[0].z = 0.001f + (float)j / 10.02f;
2055 quad[1].z = 0.001f + (float)j / 10.02f;
2056 quad[2].z = 0.001f + (float)j / 10.02f;
2057 quad[3].z = 0.001f + (float)j / 10.02f;
2059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2060 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2062 hr = IDirect3DDevice9_BeginScene(device);
2063 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2066 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2068 hr = IDirect3DDevice9_EndScene(device);
2069 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2071 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2072 color = getPixelColor(device, 128, 240);
2073 ok(color_match(color, test_data[i].color[j], 13),
2074 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2075 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2077 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2081 /* reset states */
2082 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2083 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2084 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2085 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2086 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2087 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2089 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2091 IDirect3DVertexShader9_Release(vertex_shader[1]);
2092 IDirect3DVertexShader9_Release(vertex_shader[2]);
2093 IDirect3DVertexShader9_Release(vertex_shader[3]);
2094 IDirect3DPixelShader9_Release(pixel_shader[1]);
2095 IDirect3DPixelShader9_Release(pixel_shader[2]);
2096 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2099 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2100 unsigned int i, x, y;
2101 HRESULT hr;
2102 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2103 D3DLOCKED_RECT locked_rect;
2105 /* Generate the textures */
2106 for(i=0; i<2; i++)
2108 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2109 D3DPOOL_MANAGED, &texture[i], NULL);
2110 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2112 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2113 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2114 for (y = 0; y < 128; ++y)
2116 if(i)
2117 { /* Set up black texture with 2x2 texel white spot in the middle */
2118 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2119 for (x = 0; x < 128; ++x)
2121 if(y>62 && y<66 && x>62 && x<66)
2122 *ptr++ = 0xffffffff;
2123 else
2124 *ptr++ = 0xff000000;
2127 else
2128 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2129 * (if multiplied with bumpenvmat)
2131 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2132 for (x = 0; x < 128; ++x)
2134 if(abs(x-64)>abs(y-64))
2136 if(x < 64)
2137 *ptr++ = 0xc000;
2138 else
2139 *ptr++ = 0x4000;
2141 else
2143 if(y < 64)
2144 *ptr++ = 0x0040;
2145 else
2146 *ptr++ = 0x00c0;
2151 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2152 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2154 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2155 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2157 /* Disable texture filtering */
2158 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2159 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2160 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2161 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2163 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2164 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2165 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2166 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2170 /* test the behavior of the texbem instruction
2171 * with normal 2D and projective 2D textures
2173 static void texbem_test(IDirect3DDevice9 *device)
2175 HRESULT hr;
2176 DWORD color;
2177 int i;
2179 static const DWORD pixel_shader_code[] = {
2180 0xffff0101, /* ps_1_1*/
2181 0x00000042, 0xb00f0000, /* tex t0*/
2182 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2183 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2184 0x0000ffff
2186 static const DWORD double_texbem_code[] = {
2187 0xffff0103, /* ps_1_3 */
2188 0x00000042, 0xb00f0000, /* tex t0 */
2189 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2190 0x00000042, 0xb00f0002, /* tex t2 */
2191 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2192 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2193 0x0000ffff /* end */
2197 static const float quad[][7] = {
2198 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2199 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2200 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2201 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2203 static const float quad_proj[][9] = {
2204 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2205 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2206 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2207 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2210 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2211 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2212 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2213 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2214 D3DDECL_END()
2216 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2217 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2218 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2219 D3DDECL_END()
2220 } };
2222 /* use asymmetric matrix to test loading */
2223 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2225 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2226 IDirect3DPixelShader9 *pixel_shader = NULL;
2227 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
2228 D3DLOCKED_RECT locked_rect;
2230 generate_bumpmap_textures(device);
2232 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2233 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2234 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2235 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2236 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2238 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2239 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2242 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2244 for(i=0; i<2; i++)
2246 if(i)
2248 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2249 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2252 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2253 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2254 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2255 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2257 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2258 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2259 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2260 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2262 hr = IDirect3DDevice9_BeginScene(device);
2263 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2265 if(!i)
2266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2267 else
2268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2269 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2271 hr = IDirect3DDevice9_EndScene(device);
2272 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2274 color = getPixelColor(device, 320-32, 240);
2275 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2276 color = getPixelColor(device, 320+32, 240);
2277 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2278 color = getPixelColor(device, 320, 240-32);
2279 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2280 color = getPixelColor(device, 320, 240+32);
2281 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2284 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2286 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2287 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2288 IDirect3DPixelShader9_Release(pixel_shader);
2290 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2291 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2292 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2295 /* clean up */
2296 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2297 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2299 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2300 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2302 for(i=0; i<2; i++)
2304 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2305 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2306 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2307 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2308 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2309 IDirect3DTexture9_Release(texture);
2312 /* Test double texbem */
2313 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2314 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2315 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2316 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2317 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2318 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2319 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2320 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2322 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2323 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2324 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2325 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2327 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2328 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2330 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2331 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2332 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2333 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2334 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2335 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2338 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2339 #define tex 0x00ff0000
2340 #define tex1 0x0000ff00
2341 #define origin 0x000000ff
2342 static const DWORD pixel_data[] = {
2343 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2344 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2345 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2346 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2347 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2348 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2349 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2350 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2352 #undef tex1
2353 #undef tex2
2354 #undef origin
2356 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2357 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2358 for(i = 0; i < 8; i++) {
2359 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2361 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2362 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2365 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2366 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2367 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2368 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2369 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2370 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2371 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2372 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2373 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2374 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2375 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2376 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2378 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2379 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2380 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2381 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2382 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2384 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2385 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2386 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2387 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2389 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2390 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2391 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2392 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2393 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2394 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2395 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2396 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2397 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2398 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2400 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2401 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2402 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2403 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2404 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2405 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2406 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2407 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2408 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2409 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2410 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2411 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2412 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2413 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2414 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2415 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2417 hr = IDirect3DDevice9_BeginScene(device);
2418 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2419 if(SUCCEEDED(hr)) {
2420 static const float double_quad[] = {
2421 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2422 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2423 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2424 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2428 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2429 hr = IDirect3DDevice9_EndScene(device);
2430 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2432 color = getPixelColor(device, 320, 240);
2433 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2435 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2436 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2437 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2438 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2439 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2440 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2441 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2442 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2443 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2444 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2446 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2447 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2449 IDirect3DPixelShader9_Release(pixel_shader);
2450 IDirect3DTexture9_Release(texture);
2451 IDirect3DTexture9_Release(texture1);
2452 IDirect3DTexture9_Release(texture2);
2455 static void z_range_test(IDirect3DDevice9 *device)
2457 const struct vertex quad[] =
2459 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2460 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2461 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2462 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2464 const struct vertex quad2[] =
2466 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2467 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2468 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2469 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2472 const struct tvertex quad3[] =
2474 { 0, 240, 1.1f, 1.0, 0xffffff00},
2475 { 0, 480, 1.1f, 1.0, 0xffffff00},
2476 { 640, 240, -1.1f, 1.0, 0xffffff00},
2477 { 640, 480, -1.1f, 1.0, 0xffffff00},
2479 const struct tvertex quad4[] =
2481 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2482 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2483 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2484 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2486 HRESULT hr;
2487 DWORD color;
2488 IDirect3DVertexShader9 *shader;
2489 IDirect3DVertexDeclaration9 *decl;
2490 D3DCAPS9 caps;
2491 static const DWORD shader_code[] =
2493 0xfffe0101, /* vs_1_1 */
2494 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2495 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2496 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2497 0x0000ffff /* end */
2499 static const D3DVERTEXELEMENT9 decl_elements[] = {
2500 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2501 D3DDECL_END()
2504 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2506 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2507 * then call Present. Then clear the color buffer to make sure it has some defined content
2508 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2509 * by the depth value.
2511 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2512 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2513 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2514 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2516 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2519 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2521 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2523 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2525 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2526 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2527 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2529 hr = IDirect3DDevice9_BeginScene(device);
2530 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2531 if(hr == D3D_OK)
2533 /* Test the untransformed vertex path */
2534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2535 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2537 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2539 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2541 /* Test the transformed vertex path */
2542 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2543 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2546 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2548 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2550 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2552 hr = IDirect3DDevice9_EndScene(device);
2553 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2556 /* Do not test the exact corner pixels, but go pretty close to them */
2558 /* Clipped because z > 1.0 */
2559 color = getPixelColor(device, 28, 238);
2560 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2561 color = getPixelColor(device, 28, 241);
2562 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2564 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2566 else
2568 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2571 /* Not clipped, > z buffer clear value(0.75) */
2572 color = getPixelColor(device, 31, 238);
2573 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2574 color = getPixelColor(device, 31, 241);
2575 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2576 color = getPixelColor(device, 100, 238);
2577 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2578 color = getPixelColor(device, 100, 241);
2579 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2581 /* Not clipped, < z buffer clear value */
2582 color = getPixelColor(device, 104, 238);
2583 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2584 color = getPixelColor(device, 104, 241);
2585 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2586 color = getPixelColor(device, 318, 238);
2587 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2588 color = getPixelColor(device, 318, 241);
2589 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2591 /* Clipped because z < 0.0 */
2592 color = getPixelColor(device, 321, 238);
2593 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2594 color = getPixelColor(device, 321, 241);
2595 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2597 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2599 else
2601 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2604 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2605 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2607 /* Test the shader path */
2608 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2609 skip("Vertex shaders not supported\n");
2610 goto out;
2612 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2613 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2614 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2615 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2619 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2620 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2621 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2622 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2624 hr = IDirect3DDevice9_BeginScene(device);
2625 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2626 if(hr == D3D_OK)
2628 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2629 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2630 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2632 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2633 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2634 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2635 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2637 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2639 hr = IDirect3DDevice9_EndScene(device);
2640 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2643 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2644 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2645 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2646 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2648 IDirect3DVertexDeclaration9_Release(decl);
2649 IDirect3DVertexShader9_Release(shader);
2651 /* Z < 1.0 */
2652 color = getPixelColor(device, 28, 238);
2653 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2655 /* 1.0 < z < 0.75 */
2656 color = getPixelColor(device, 31, 238);
2657 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2658 color = getPixelColor(device, 100, 238);
2659 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2661 /* 0.75 < z < 0.0 */
2662 color = getPixelColor(device, 104, 238);
2663 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2664 color = getPixelColor(device, 318, 238);
2665 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2667 /* 0.0 < z */
2668 color = getPixelColor(device, 321, 238);
2669 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2671 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2672 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2674 out:
2675 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2676 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2677 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2678 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2680 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2683 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2685 D3DSURFACE_DESC desc;
2686 D3DLOCKED_RECT l;
2687 HRESULT hr;
2688 unsigned int x, y;
2689 DWORD *mem;
2691 memset(&desc, 0, sizeof(desc));
2692 memset(&l, 0, sizeof(l));
2693 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2694 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2695 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2696 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2697 if(FAILED(hr)) return;
2699 for(y = 0; y < desc.Height; y++)
2701 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2702 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2704 mem[x] = color;
2707 hr = IDirect3DSurface9_UnlockRect(surface);
2708 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2711 /* This tests a variety of possible StretchRect() situations */
2712 static void stretchrect_test(IDirect3DDevice9 *device)
2714 HRESULT hr;
2715 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2716 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2717 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2718 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2719 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2720 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2721 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2722 IDirect3DSurface9 *orig_rt = NULL;
2723 IDirect3DSurface9 *backbuffer = NULL;
2724 DWORD color;
2726 RECT src_rect64 = {0, 0, 64, 64};
2727 RECT src_rect64_flipy = {0, 64, 64, 0};
2728 RECT dst_rect64 = {0, 0, 64, 64};
2729 RECT dst_rect64_flipy = {0, 64, 64, 0};
2731 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2732 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2733 if(!orig_rt) {
2734 goto out;
2737 /* Create our temporary surfaces in system memory */
2738 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2739 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2740 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2741 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2743 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2744 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2745 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2746 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2747 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2748 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2749 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2751 /* Create render target surfaces */
2752 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2753 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2754 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2755 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2756 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2757 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2758 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2759 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2761 /* Create render target textures */
2762 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2763 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2764 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2765 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2766 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2767 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2768 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2769 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2770 if (tex_rt32) {
2771 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2772 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2774 if (tex_rt64) {
2775 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2776 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2778 if (tex_rt_dest64) {
2779 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2780 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2782 if (tex_rt_dest640_480) {
2783 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2784 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2787 /* Create regular textures in D3DPOOL_DEFAULT */
2788 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2789 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2790 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2791 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2792 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2793 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2794 if (tex32) {
2795 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2796 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2798 if (tex64) {
2799 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2800 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2802 if (tex_dest64) {
2803 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2804 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2807 /*********************************************************************
2808 * Tests for when the source parameter is an offscreen plain surface *
2809 *********************************************************************/
2811 /* Fill the offscreen 64x64 surface with green */
2812 if (surf_offscreen64)
2813 fill_surface(surf_offscreen64, 0xff00ff00);
2815 /* offscreenplain ==> offscreenplain, same size */
2816 if(surf_offscreen64 && surf_offscreen_dest64) {
2817 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2818 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2820 if (hr == D3D_OK) {
2821 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2822 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2825 /* Blit without scaling */
2826 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2827 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2830 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2831 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2834 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2835 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838 /* offscreenplain ==> rendertarget texture, same size */
2839 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2840 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2841 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2843 /* We can't lock rendertarget textures, so copy to our temp surface first */
2844 if (hr == D3D_OK) {
2845 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2846 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2849 if (hr == D3D_OK) {
2850 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2851 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2854 /* Blit without scaling */
2855 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2856 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2858 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2859 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2860 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2862 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2863 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2864 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2867 /* offscreenplain ==> rendertarget surface, same size */
2868 if(surf_offscreen64 && surf_rt_dest64) {
2869 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2870 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2872 if (hr == D3D_OK) {
2873 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2874 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2877 /* Blit without scaling */
2878 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2879 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2881 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2882 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2883 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2885 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2886 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2887 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2890 /* offscreenplain ==> texture, same size (should fail) */
2891 if(surf_offscreen64 && surf_tex_dest64) {
2892 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2893 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2896 /* Fill the smaller offscreen surface with red */
2897 fill_surface(surf_offscreen32, 0xffff0000);
2899 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2900 if(surf_offscreen32 && surf_offscreen64) {
2901 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2902 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2905 /* offscreenplain ==> rendertarget texture, scaling */
2906 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2907 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2908 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2910 /* We can't lock rendertarget textures, so copy to our temp surface first */
2911 if (hr == D3D_OK) {
2912 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2913 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2916 if (hr == D3D_OK) {
2917 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2918 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2922 /* offscreenplain ==> rendertarget surface, scaling */
2923 if(surf_offscreen32 && surf_rt_dest64) {
2924 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2925 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2927 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2928 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2931 /* offscreenplain ==> texture, scaling (should fail) */
2932 if(surf_offscreen32 && surf_tex_dest64) {
2933 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2934 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2937 /************************************************************
2938 * Tests for when the source parameter is a regular texture *
2939 ************************************************************/
2941 /* Fill the surface of the regular texture with blue */
2942 if (surf_tex64 && surf_temp64) {
2943 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2944 fill_surface(surf_temp64, 0xff0000ff);
2945 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2946 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2949 /* texture ==> offscreenplain, same size */
2950 if(surf_tex64 && surf_offscreen64) {
2951 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2952 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2955 /* texture ==> rendertarget texture, same size */
2956 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2957 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2958 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960 /* We can't lock rendertarget textures, so copy to our temp surface first */
2961 if (hr == D3D_OK) {
2962 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2963 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2966 if (hr == D3D_OK) {
2967 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2968 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2971 /* Blit without scaling */
2972 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2973 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2975 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2976 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2977 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2979 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2980 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2981 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2984 /* texture ==> rendertarget surface, same size */
2985 if(surf_tex64 && surf_rt_dest64) {
2986 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2987 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2989 if (hr == D3D_OK) {
2990 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2991 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2994 /* Blit without scaling */
2995 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2996 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2998 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2999 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3000 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3002 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3003 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3004 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3007 /* texture ==> texture, same size (should fail) */
3008 if(surf_tex64 && surf_tex_dest64) {
3009 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
3010 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3013 /* Fill the surface of the smaller regular texture with red */
3014 if (surf_tex32 && surf_temp32) {
3015 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
3016 fill_surface(surf_temp32, 0xffff0000);
3017 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3018 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3021 /* texture ==> offscreenplain, scaling (should fail) */
3022 if(surf_tex32 && surf_offscreen64) {
3023 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
3024 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3027 /* texture ==> rendertarget texture, scaling */
3028 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3029 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3030 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3032 /* We can't lock rendertarget textures, so copy to our temp surface first */
3033 if (hr == D3D_OK) {
3034 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3035 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3038 if (hr == D3D_OK) {
3039 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3040 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3044 /* texture ==> rendertarget surface, scaling */
3045 if(surf_tex32 && surf_rt_dest64) {
3046 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3047 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3049 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3050 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3053 /* texture ==> texture, scaling (should fail) */
3054 if(surf_tex32 && surf_tex_dest64) {
3055 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3056 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3059 /*****************************************************************
3060 * Tests for when the source parameter is a rendertarget texture *
3061 *****************************************************************/
3063 /* Fill the surface of the rendertarget texture with white */
3064 if (surf_tex_rt64 && surf_temp64) {
3065 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3066 fill_surface(surf_temp64, 0xffffffff);
3067 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3068 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3071 /* rendertarget texture ==> offscreenplain, same size */
3072 if(surf_tex_rt64 && surf_offscreen64) {
3073 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3074 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3077 /* rendertarget texture ==> rendertarget texture, same size */
3078 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3079 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3080 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082 /* We can't lock rendertarget textures, so copy to our temp surface first */
3083 if (hr == D3D_OK) {
3084 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3085 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3088 if (hr == D3D_OK) {
3089 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3090 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3093 /* Blit without scaling */
3094 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3095 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3097 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3098 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3099 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3101 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3102 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3103 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3106 /* rendertarget texture ==> rendertarget surface, same size */
3107 if(surf_tex_rt64 && surf_rt_dest64) {
3108 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3109 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3111 if (hr == D3D_OK) {
3112 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3113 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3116 /* Blit without scaling */
3117 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3118 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3120 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3121 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3122 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3124 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3125 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3126 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3129 /* rendertarget texture ==> texture, same size (should fail) */
3130 if(surf_tex_rt64 && surf_tex_dest64) {
3131 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3132 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3135 /* Fill the surface of the smaller rendertarget texture with red */
3136 if (surf_tex_rt32 && surf_temp32) {
3137 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3138 fill_surface(surf_temp32, 0xffff0000);
3139 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3140 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3143 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3144 if(surf_tex_rt32 && surf_offscreen64) {
3145 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3146 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3149 /* rendertarget texture ==> rendertarget texture, scaling */
3150 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3151 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3152 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3154 /* We can't lock rendertarget textures, so copy to our temp surface first */
3155 if (hr == D3D_OK) {
3156 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3157 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3160 if (hr == D3D_OK) {
3161 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3162 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3166 /* rendertarget texture ==> rendertarget surface, scaling */
3167 if(surf_tex_rt32 && surf_rt_dest64) {
3168 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3169 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3172 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3175 /* rendertarget texture ==> texture, scaling (should fail) */
3176 if(surf_tex_rt32 && surf_tex_dest64) {
3177 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3178 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3181 /*****************************************************************
3182 * Tests for when the source parameter is a rendertarget surface *
3183 *****************************************************************/
3185 /* Fill the surface of the rendertarget surface with black */
3186 if (surf_rt64)
3187 fill_surface(surf_rt64, 0xff000000);
3189 /* rendertarget texture ==> offscreenplain, same size */
3190 if(surf_rt64 && surf_offscreen64) {
3191 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3192 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3195 /* rendertarget surface ==> rendertarget texture, same size */
3196 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3197 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3198 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3200 /* We can't lock rendertarget textures, so copy to our temp surface first */
3201 if (hr == D3D_OK) {
3202 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3203 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3206 if (hr == D3D_OK) {
3207 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3208 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3211 /* Blit without scaling */
3212 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3213 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3215 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3216 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3217 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3219 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3220 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3221 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3224 /* rendertarget surface ==> rendertarget surface, same size */
3225 if(surf_rt64 && surf_rt_dest64) {
3226 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3227 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3229 if (hr == D3D_OK) {
3230 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3231 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3234 /* Blit without scaling */
3235 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3236 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3238 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3239 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3240 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3242 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3243 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3244 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3247 /* rendertarget surface ==> texture, same size (should fail) */
3248 if(surf_rt64 && surf_tex_dest64) {
3249 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3250 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3253 /* Fill the surface of the smaller rendertarget texture with red */
3254 if (surf_rt32)
3255 fill_surface(surf_rt32, 0xffff0000);
3257 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3258 if(surf_rt32 && surf_offscreen64) {
3259 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3260 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3263 /* rendertarget surface ==> rendertarget texture, scaling */
3264 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3265 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3266 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3268 /* We can't lock rendertarget textures, so copy to our temp surface first */
3269 if (hr == D3D_OK) {
3270 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3271 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3274 if (hr == D3D_OK) {
3275 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3276 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3280 /* rendertarget surface ==> rendertarget surface, scaling */
3281 if(surf_rt32 && surf_rt_dest64) {
3282 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3283 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3285 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3286 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3289 /* rendertarget surface ==> texture, scaling (should fail) */
3290 if(surf_rt32 && surf_tex_dest64) {
3291 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3292 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3295 /* backbuffer ==> surface tests (no scaling) */
3296 if(backbuffer && surf_tex_rt_dest640_480)
3298 RECT src_rect = {0, 0, 640, 480};
3299 RECT src_rect_flipy = {0, 480, 640, 0};
3300 RECT dst_rect = {0, 0, 640, 480};
3301 RECT dst_rect_flipy = {0, 480, 640, 0};
3303 /* Blit with NULL rectangles */
3304 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3305 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3307 /* Blit without scaling */
3308 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3309 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3311 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3312 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3313 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3315 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3316 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3317 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3320 /* TODO: Test format conversions */
3323 out:
3324 /* Clean up */
3325 if (backbuffer)
3326 IDirect3DSurface9_Release(backbuffer);
3327 if (surf_rt32)
3328 IDirect3DSurface9_Release(surf_rt32);
3329 if (surf_rt64)
3330 IDirect3DSurface9_Release(surf_rt64);
3331 if (surf_rt_dest64)
3332 IDirect3DSurface9_Release(surf_rt_dest64);
3333 if (surf_temp32)
3334 IDirect3DSurface9_Release(surf_temp32);
3335 if (surf_temp64)
3336 IDirect3DSurface9_Release(surf_temp64);
3337 if (surf_offscreen32)
3338 IDirect3DSurface9_Release(surf_offscreen32);
3339 if (surf_offscreen64)
3340 IDirect3DSurface9_Release(surf_offscreen64);
3341 if (surf_offscreen_dest64)
3342 IDirect3DSurface9_Release(surf_offscreen_dest64);
3344 if (tex_rt32) {
3345 if (surf_tex_rt32)
3346 IDirect3DSurface9_Release(surf_tex_rt32);
3347 IDirect3DTexture9_Release(tex_rt32);
3349 if (tex_rt64) {
3350 if (surf_tex_rt64)
3351 IDirect3DSurface9_Release(surf_tex_rt64);
3352 IDirect3DTexture9_Release(tex_rt64);
3354 if (tex_rt_dest64) {
3355 if (surf_tex_rt_dest64)
3356 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3357 IDirect3DTexture9_Release(tex_rt_dest64);
3359 if (tex_rt_dest640_480) {
3360 if (surf_tex_rt_dest640_480)
3361 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3362 IDirect3DTexture9_Release(tex_rt_dest640_480);
3364 if (tex32) {
3365 if (surf_tex32)
3366 IDirect3DSurface9_Release(surf_tex32);
3367 IDirect3DTexture9_Release(tex32);
3369 if (tex64) {
3370 if (surf_tex64)
3371 IDirect3DSurface9_Release(surf_tex64);
3372 IDirect3DTexture9_Release(tex64);
3374 if (tex_dest64) {
3375 if (surf_tex_dest64)
3376 IDirect3DSurface9_Release(surf_tex_dest64);
3377 IDirect3DTexture9_Release(tex_dest64);
3380 if (orig_rt) {
3381 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3382 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3383 IDirect3DSurface9_Release(orig_rt);
3387 static void maxmip_test(IDirect3DDevice9 *device)
3389 IDirect3DTexture9 *texture = NULL;
3390 IDirect3DSurface9 *surface = NULL;
3391 HRESULT hr;
3392 DWORD color;
3393 static const struct
3395 struct
3397 float x, y, z;
3398 float s, t;
3400 v[4];
3402 quads[] =
3405 {-1.0, -1.0, 0.0, 0.0, 0.0},
3406 {-1.0, 0.0, 0.0, 0.0, 1.0},
3407 { 0.0, -1.0, 0.0, 1.0, 0.0},
3408 { 0.0, 0.0, 0.0, 1.0, 1.0},
3411 { 0.0, -1.0, 0.0, 0.0, 0.0},
3412 { 0.0, 0.0, 0.0, 0.0, 1.0},
3413 { 1.0, -1.0, 0.0, 1.0, 0.0},
3414 { 1.0, 0.0, 0.0, 1.0, 1.0},
3417 { 0.0, 0.0, 0.0, 0.0, 0.0},
3418 { 0.0, 1.0, 0.0, 0.0, 1.0},
3419 { 1.0, 0.0, 0.0, 1.0, 0.0},
3420 { 1.0, 1.0, 0.0, 1.0, 1.0},
3423 {-1.0, 0.0, 0.0, 0.0, 0.0},
3424 {-1.0, 1.0, 0.0, 0.0, 1.0},
3425 { 0.0, 0.0, 0.0, 1.0, 0.0},
3426 { 0.0, 1.0, 0.0, 1.0, 1.0},
3430 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3431 &texture, NULL);
3432 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3433 if(!texture)
3435 skip("Failed to create test texture\n");
3436 return;
3439 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3440 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3441 fill_surface(surface, 0xffff0000);
3442 IDirect3DSurface9_Release(surface);
3443 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3444 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3445 fill_surface(surface, 0xff00ff00);
3446 IDirect3DSurface9_Release(surface);
3447 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3448 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3449 fill_surface(surface, 0xff0000ff);
3450 IDirect3DSurface9_Release(surface);
3452 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3453 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3454 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3455 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3457 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3458 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3461 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3463 hr = IDirect3DDevice9_BeginScene(device);
3464 if(SUCCEEDED(hr))
3466 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3469 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3471 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3472 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3474 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3476 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3477 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3479 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3481 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3482 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3484 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3485 hr = IDirect3DDevice9_EndScene(device);
3486 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3489 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3490 color = getPixelColor(device, 160, 360);
3491 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3492 color = getPixelColor(device, 480, 360);
3493 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3494 color = getPixelColor(device, 480, 120);
3495 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3496 color = getPixelColor(device, 160, 120);
3497 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3498 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3499 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3501 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3502 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3504 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3507 hr = IDirect3DDevice9_BeginScene(device);
3508 if(SUCCEEDED(hr))
3510 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3511 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3512 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3513 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3515 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3516 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3518 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3520 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3521 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3522 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3523 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3525 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3526 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3527 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3528 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3529 hr = IDirect3DDevice9_EndScene(device);
3530 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3533 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3534 * level 3 (> levels in texture) samples from the highest level in the
3535 * texture (level 2). */
3536 color = getPixelColor(device, 160, 360);
3537 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3538 color = getPixelColor(device, 480, 360);
3539 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3540 color = getPixelColor(device, 480, 120);
3541 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3542 color = getPixelColor(device, 160, 120);
3543 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3544 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3545 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3547 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3548 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3550 hr = IDirect3DDevice9_BeginScene(device);
3551 if(SUCCEEDED(hr))
3553 DWORD ret;
3555 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3556 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3557 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3558 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3559 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3560 ret = IDirect3DTexture9_SetLOD(texture, 1);
3561 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3563 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3565 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3566 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3567 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3568 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3569 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3570 ret = IDirect3DTexture9_SetLOD(texture, 2);
3571 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3573 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3575 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3576 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3577 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3578 ret = IDirect3DTexture9_SetLOD(texture, 1);
3579 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3581 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3583 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3584 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3585 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3586 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3587 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3588 ret = IDirect3DTexture9_SetLOD(texture, 1);
3589 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3590 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3591 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3592 hr = IDirect3DDevice9_EndScene(device);
3593 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3596 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3597 * level 3 (> levels in texture) samples from the highest level in the
3598 * texture (level 2). */
3599 color = getPixelColor(device, 160, 360);
3600 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3601 color = getPixelColor(device, 480, 360);
3602 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3603 color = getPixelColor(device, 480, 120);
3604 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3605 color = getPixelColor(device, 160, 120);
3606 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3608 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3609 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3611 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3612 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3613 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3614 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3615 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3616 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3617 IDirect3DTexture9_Release(texture);
3620 static void release_buffer_test(IDirect3DDevice9 *device)
3622 IDirect3DVertexBuffer9 *vb = NULL;
3623 IDirect3DIndexBuffer9 *ib = NULL;
3624 HRESULT hr;
3625 BYTE *data;
3626 LONG ref;
3628 static const struct vertex quad[] = {
3629 {-1.0, -1.0, 0.1, 0xffff0000},
3630 {-1.0, 1.0, 0.1, 0xffff0000},
3631 { 1.0, 1.0, 0.1, 0xffff0000},
3633 {-1.0, -1.0, 0.1, 0xff00ff00},
3634 {-1.0, 1.0, 0.1, 0xff00ff00},
3635 { 1.0, 1.0, 0.1, 0xff00ff00}
3637 short indices[] = {3, 4, 5};
3639 /* Index and vertex buffers should always be creatable */
3640 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3641 D3DPOOL_MANAGED, &vb, NULL);
3642 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3643 if(!vb) {
3644 skip("Failed to create a vertex buffer\n");
3645 return;
3647 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3648 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3649 if(!ib) {
3650 skip("Failed to create an index buffer\n");
3651 return;
3654 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3655 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3656 memcpy(data, quad, sizeof(quad));
3657 hr = IDirect3DVertexBuffer9_Unlock(vb);
3658 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3660 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3661 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3662 memcpy(data, indices, sizeof(indices));
3663 hr = IDirect3DIndexBuffer9_Unlock(ib);
3664 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3666 hr = IDirect3DDevice9_SetIndices(device, ib);
3667 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3668 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3669 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3673 /* Now destroy the bound index buffer and draw again */
3674 ref = IDirect3DIndexBuffer9_Release(ib);
3675 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3677 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3678 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3680 hr = IDirect3DDevice9_BeginScene(device);
3681 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3682 if(SUCCEEDED(hr))
3684 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3685 * making assumptions about the indices or vertices
3687 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3688 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3689 hr = IDirect3DDevice9_EndScene(device);
3690 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3693 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3694 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3696 hr = IDirect3DDevice9_SetIndices(device, NULL);
3697 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3698 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3699 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3701 /* Index buffer was already destroyed as part of the test */
3702 IDirect3DVertexBuffer9_Release(vb);
3705 static void float_texture_test(IDirect3DDevice9 *device)
3707 IDirect3D9 *d3d = NULL;
3708 HRESULT hr;
3709 IDirect3DTexture9 *texture = NULL;
3710 D3DLOCKED_RECT lr;
3711 float *data;
3712 DWORD color;
3713 float quad[] = {
3714 -1.0, -1.0, 0.1, 0.0, 0.0,
3715 -1.0, 1.0, 0.1, 0.0, 1.0,
3716 1.0, -1.0, 0.1, 1.0, 0.0,
3717 1.0, 1.0, 0.1, 1.0, 1.0,
3720 memset(&lr, 0, sizeof(lr));
3721 IDirect3DDevice9_GetDirect3D(device, &d3d);
3722 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3723 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3724 skip("D3DFMT_R32F textures not supported\n");
3725 goto out;
3728 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3729 D3DPOOL_MANAGED, &texture, NULL);
3730 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3731 if(!texture) {
3732 skip("Failed to create R32F texture\n");
3733 goto out;
3736 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3737 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3738 data = lr.pBits;
3739 *data = 0.0;
3740 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3741 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3743 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3744 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3746 hr = IDirect3DDevice9_BeginScene(device);
3747 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3748 if(SUCCEEDED(hr))
3750 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3754 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3756 hr = IDirect3DDevice9_EndScene(device);
3757 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3759 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3762 color = getPixelColor(device, 240, 320);
3763 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
3765 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3768 out:
3769 if(texture) IDirect3DTexture9_Release(texture);
3770 IDirect3D9_Release(d3d);
3773 static void g16r16_texture_test(IDirect3DDevice9 *device)
3775 IDirect3D9 *d3d = NULL;
3776 HRESULT hr;
3777 IDirect3DTexture9 *texture = NULL;
3778 D3DLOCKED_RECT lr;
3779 DWORD *data;
3780 DWORD color;
3781 float quad[] = {
3782 -1.0, -1.0, 0.1, 0.0, 0.0,
3783 -1.0, 1.0, 0.1, 0.0, 1.0,
3784 1.0, -1.0, 0.1, 1.0, 0.0,
3785 1.0, 1.0, 0.1, 1.0, 1.0,
3788 memset(&lr, 0, sizeof(lr));
3789 IDirect3DDevice9_GetDirect3D(device, &d3d);
3790 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3791 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3792 skip("D3DFMT_G16R16 textures not supported\n");
3793 goto out;
3796 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3797 D3DPOOL_MANAGED, &texture, NULL);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3799 if(!texture) {
3800 skip("Failed to create D3DFMT_G16R16 texture\n");
3801 goto out;
3804 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3805 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3806 data = lr.pBits;
3807 *data = 0x0f00f000;
3808 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3809 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3811 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3812 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3814 hr = IDirect3DDevice9_BeginScene(device);
3815 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3816 if(SUCCEEDED(hr))
3818 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3819 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3824 hr = IDirect3DDevice9_EndScene(device);
3825 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3827 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3828 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3830 color = getPixelColor(device, 240, 320);
3831 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3832 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3834 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3835 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3837 out:
3838 if(texture) IDirect3DTexture9_Release(texture);
3839 IDirect3D9_Release(d3d);
3842 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3844 LONG x_coords[2][2] =
3846 {r.left - 1, r.left + 1},
3847 {r.right + 1, r.right - 1},
3849 LONG y_coords[2][2] =
3851 {r.top - 1, r.top + 1},
3852 {r.bottom + 1, r.bottom - 1}
3854 unsigned int i, j, x_side, y_side;
3856 for (i = 0; i < 2; ++i)
3858 for (j = 0; j < 2; ++j)
3860 for (x_side = 0; x_side < 2; ++x_side)
3862 for (y_side = 0; y_side < 2; ++y_side)
3864 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3865 DWORD color;
3866 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3868 color = getPixelColor(device, x, y);
3869 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3870 message, x, y, color, expected);
3877 struct projected_textures_test_run
3879 const char *message;
3880 DWORD flags;
3881 IDirect3DVertexDeclaration9 *decl;
3882 BOOL vs, ps;
3883 RECT rect;
3886 static void projected_textures_test(IDirect3DDevice9 *device,
3887 struct projected_textures_test_run tests[4])
3889 unsigned int i;
3891 static const DWORD vertex_shader[] =
3893 0xfffe0101, /* vs_1_1 */
3894 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3895 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
3896 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3897 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
3898 0x0000ffff /* end */
3900 static const DWORD pixel_shader[] =
3902 0xffff0103, /* ps_1_3 */
3903 0x00000042, 0xb00f0000, /* tex t0 */
3904 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3905 0x0000ffff /* end */
3907 IDirect3DVertexShader9 *vs = NULL;
3908 IDirect3DPixelShader9 *ps = NULL;
3909 IDirect3D9 *d3d;
3910 D3DCAPS9 caps;
3911 HRESULT hr;
3913 IDirect3DDevice9_GetDirect3D(device, &d3d);
3914 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3915 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
3916 IDirect3D9_Release(d3d);
3918 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3920 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3921 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3923 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
3925 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3926 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3929 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3930 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3932 hr = IDirect3DDevice9_BeginScene(device);
3933 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3934 if (FAILED(hr))
3935 return;
3937 for (i = 0; i < 4; ++i)
3939 DWORD value = 0xdeadbeef;
3940 static const float proj_quads[] =
3942 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3943 0.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3944 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3945 0.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3947 0.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3948 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3949 0.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3950 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3952 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3953 0.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3954 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3955 0.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3957 0.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3958 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3959 0.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3960 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3963 if (tests[i].vs)
3965 if (!vs)
3967 skip("Vertex shaders not supported, skipping\n");
3968 continue;
3970 hr = IDirect3DDevice9_SetVertexShader(device, vs);
3972 else
3973 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3974 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3975 if (tests[i].ps)
3977 if (!ps)
3979 skip("Pixel shaders not supported, skipping\n");
3980 continue;
3982 hr = IDirect3DDevice9_SetPixelShader(device, ps);
3984 else
3985 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3986 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3988 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3989 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3991 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3992 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3993 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3994 ok(SUCCEEDED(hr) && value == tests[i].flags,
3995 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3998 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4002 hr = IDirect3DDevice9_EndScene(device);
4003 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4005 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4006 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4007 if (vs) IDirect3DVertexShader9_Release(vs);
4008 if (ps) IDirect3DPixelShader9_Release(ps);
4010 for (i = 0; i < 4; ++i)
4012 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4013 check_rect(device, tests[i].rect, tests[i].message);
4016 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4017 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4020 static void texture_transform_flags_test(IDirect3DDevice9 *device)
4022 HRESULT hr;
4023 IDirect3D9 *d3d;
4024 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4025 D3DCAPS9 caps;
4026 IDirect3DTexture9 *texture = NULL;
4027 IDirect3DVolumeTexture9 *volume = NULL;
4028 unsigned int x, y, z;
4029 D3DLOCKED_RECT lr;
4030 D3DLOCKED_BOX lb;
4031 DWORD color;
4032 UINT w, h;
4033 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4034 float identity[16] = {1.0, 0.0, 0.0, 0.0,
4035 0.0, 1.0, 0.0, 0.0,
4036 0.0, 0.0, 1.0, 0.0,
4037 0.0, 0.0, 0.0, 1.0};
4038 static const D3DVERTEXELEMENT9 decl_elements[] = {
4039 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4040 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4041 D3DDECL_END()
4043 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4044 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4045 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4046 D3DDECL_END()
4048 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4049 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4050 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4051 D3DDECL_END()
4053 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4054 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4055 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4056 D3DDECL_END()
4058 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4059 0x00, 0xff, 0x00, 0x00,
4060 0x00, 0x00, 0x00, 0x00,
4061 0x00, 0x00, 0x00, 0x00};
4063 memset(&lr, 0, sizeof(lr));
4064 memset(&lb, 0, sizeof(lb));
4065 IDirect3DDevice9_GetDirect3D(device, &d3d);
4066 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4067 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4068 fmt = D3DFMT_A16B16G16R16;
4070 IDirect3D9_Release(d3d);
4072 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4073 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4074 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4075 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4076 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4077 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4078 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4079 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4080 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4081 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4082 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4083 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4084 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4085 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4086 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4087 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4088 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4089 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4090 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4091 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4092 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4093 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4094 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4095 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4096 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4097 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4100 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4101 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4103 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4104 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4105 w = min(1024, caps.MaxTextureWidth);
4106 h = min(1024, caps.MaxTextureHeight);
4107 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4108 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4109 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4110 if(!texture) {
4111 skip("Failed to create the test texture\n");
4112 return;
4115 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4116 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4117 * 1.0 in red and green for the x and y coords
4119 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4120 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4121 for(y = 0; y < h; y++) {
4122 for(x = 0; x < w; x++) {
4123 double r_f = (double) y / (double) h;
4124 double g_f = (double) x / (double) w;
4125 if(fmt == D3DFMT_A16B16G16R16) {
4126 unsigned short r, g;
4127 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4128 r = (unsigned short) (r_f * 65536.0);
4129 g = (unsigned short) (g_f * 65536.0);
4130 dst[0] = r;
4131 dst[1] = g;
4132 dst[2] = 0;
4133 dst[3] = 65535;
4134 } else {
4135 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4136 unsigned char r = (unsigned char) (r_f * 255.0);
4137 unsigned char g = (unsigned char) (g_f * 255.0);
4138 dst[0] = 0;
4139 dst[1] = g;
4140 dst[2] = r;
4141 dst[3] = 255;
4145 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4146 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4147 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4148 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4151 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4152 hr = IDirect3DDevice9_BeginScene(device);
4153 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4154 if(SUCCEEDED(hr))
4156 float quad1[] = {
4157 -1.0, -1.0, 0.1, 1.0, 1.0,
4158 -1.0, 0.0, 0.1, 1.0, 1.0,
4159 0.0, -1.0, 0.1, 1.0, 1.0,
4160 0.0, 0.0, 0.1, 1.0, 1.0,
4162 float quad2[] = {
4163 -1.0, 0.0, 0.1, 1.0, 1.0,
4164 -1.0, 1.0, 0.1, 1.0, 1.0,
4165 0.0, 0.0, 0.1, 1.0, 1.0,
4166 0.0, 1.0, 0.1, 1.0, 1.0,
4168 float quad3[] = {
4169 0.0, 0.0, 0.1, 0.5, 0.5,
4170 0.0, 1.0, 0.1, 0.5, 0.5,
4171 1.0, 0.0, 0.1, 0.5, 0.5,
4172 1.0, 1.0, 0.1, 0.5, 0.5,
4174 float quad4[] = {
4175 320, 480, 0.1, 1.0, 0.0, 1.0,
4176 320, 240, 0.1, 1.0, 0.0, 1.0,
4177 640, 480, 0.1, 1.0, 0.0, 1.0,
4178 640, 240, 0.1, 1.0, 0.0, 1.0,
4180 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4181 0.0, 0.0, 0.0, 0.0,
4182 0.0, 0.0, 0.0, 0.0,
4183 0.0, 0.0, 0.0, 0.0};
4185 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4186 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4187 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4189 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4191 /* What happens with transforms enabled? */
4192 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4193 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4194 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4195 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4197 /* What happens if 4 coords are used, but only 2 given ?*/
4198 mat[8] = 1.0;
4199 mat[13] = 1.0;
4200 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4201 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4202 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4203 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4205 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4207 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4208 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4209 * due to the coords in the vertices. (turns out red, indeed)
4211 memset(mat, 0, sizeof(mat));
4212 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4213 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4214 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4216 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4217 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4219 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4221 hr = IDirect3DDevice9_EndScene(device);
4222 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4224 color = getPixelColor(device, 160, 360);
4225 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4226 color = getPixelColor(device, 160, 120);
4227 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4228 color = getPixelColor(device, 480, 120);
4229 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4230 color = getPixelColor(device, 480, 360);
4231 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4232 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4233 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4235 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4236 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4238 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4239 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4240 hr = IDirect3DDevice9_BeginScene(device);
4241 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4242 if(SUCCEEDED(hr))
4244 float quad1[] = {
4245 -1.0, -1.0, 0.1, 0.8, 0.2,
4246 -1.0, 0.0, 0.1, 0.8, 0.2,
4247 0.0, -1.0, 0.1, 0.8, 0.2,
4248 0.0, 0.0, 0.1, 0.8, 0.2,
4250 float quad2[] = {
4251 -1.0, 0.0, 0.1, 0.5, 1.0,
4252 -1.0, 1.0, 0.1, 0.5, 1.0,
4253 0.0, 0.0, 0.1, 0.5, 1.0,
4254 0.0, 1.0, 0.1, 0.5, 1.0,
4256 float quad3[] = {
4257 0.0, 0.0, 0.1, 0.5, 1.0,
4258 0.0, 1.0, 0.1, 0.5, 1.0,
4259 1.0, 0.0, 0.1, 0.5, 1.0,
4260 1.0, 1.0, 0.1, 0.5, 1.0,
4262 float quad4[] = {
4263 0.0, -1.0, 0.1, 0.8, 0.2,
4264 0.0, 0.0, 0.1, 0.8, 0.2,
4265 1.0, -1.0, 0.1, 0.8, 0.2,
4266 1.0, 0.0, 0.1, 0.8, 0.2,
4268 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4269 0.0, 0.0, 0.0, 0.0,
4270 0.0, 1.0, 0.0, 0.0,
4271 0.0, 0.0, 0.0, 0.0};
4273 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4274 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4276 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4277 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4279 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4280 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4282 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4283 * it behaves like COUNT2 because normal textures require 2 coords. */
4284 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4285 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4287 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4289 /* Just to be sure, the same as quad2 above */
4290 memset(mat, 0, sizeof(mat));
4291 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4292 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4293 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4294 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4296 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4298 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4299 * used? And what happens to the first? */
4300 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4303 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4305 hr = IDirect3DDevice9_EndScene(device);
4306 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4308 color = getPixelColor(device, 160, 360);
4309 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4310 color = getPixelColor(device, 160, 120);
4311 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4312 color = getPixelColor(device, 480, 120);
4313 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4314 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4315 color = getPixelColor(device, 480, 360);
4316 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4317 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4318 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4319 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4321 IDirect3DTexture9_Release(texture);
4323 /* Test projected textures, without any fancy matrices */
4324 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4325 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4326 if (SUCCEEDED(hr))
4328 struct projected_textures_test_run projected_tests_1[4] =
4331 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4332 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4333 decl3,
4334 FALSE, TRUE,
4335 {120, 300, 240, 390},
4338 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4339 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4340 decl3,
4341 FALSE, TRUE,
4342 {400, 360, 480, 420},
4344 /* Try with some invalid values */
4346 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4347 0xffffffff,
4348 decl3,
4349 FALSE, TRUE,
4350 {120, 60, 240, 150}
4353 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4354 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4355 decl4,
4356 FALSE, TRUE,
4357 {340, 210, 360, 225},
4360 struct projected_textures_test_run projected_tests_2[4] =
4363 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4364 D3DTTFF_PROJECTED,
4365 decl3,
4366 FALSE, TRUE,
4367 {120, 300, 240, 390},
4370 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4371 D3DTTFF_PROJECTED,
4372 decl,
4373 FALSE, TRUE,
4374 {400, 360, 480, 420},
4377 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4378 0xffffffff,
4379 decl,
4380 FALSE, TRUE,
4381 {80, 120, 160, 180},
4384 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4385 D3DTTFF_COUNT1,
4386 decl4,
4387 FALSE, TRUE,
4388 {340, 210, 360, 225},
4391 struct projected_textures_test_run projected_tests_3[4] =
4394 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4395 D3DTTFF_PROJECTED,
4396 decl3,
4397 TRUE, FALSE,
4398 {120, 300, 240, 390},
4401 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4402 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4403 decl3,
4404 TRUE, TRUE,
4405 {440, 300, 560, 390},
4408 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4409 0xffffffff,
4410 decl3,
4411 TRUE, TRUE,
4412 {120, 60, 240, 150},
4415 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4416 D3DTTFF_PROJECTED,
4417 decl3,
4418 FALSE, FALSE,
4419 {440, 60, 560, 150},
4423 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4424 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4426 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4427 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4428 for(x = 0; x < 4; x++) {
4429 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4431 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4432 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4433 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4434 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4436 projected_textures_test(device, projected_tests_1);
4437 projected_textures_test(device, projected_tests_2);
4438 projected_textures_test(device, projected_tests_3);
4440 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4441 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4442 IDirect3DTexture9_Release(texture);
4445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4446 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4447 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4448 * Thus watch out if sampling from texels between 0 and 1.
4450 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4451 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4452 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4453 if(!volume) {
4454 skip("Failed to create a volume texture\n");
4455 goto out;
4458 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4459 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4460 for(z = 0; z < 32; z++) {
4461 for(y = 0; y < 32; y++) {
4462 for(x = 0; x < 32; x++) {
4463 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4464 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4465 float r_f = (float) x / 31.0;
4466 float g_f = (float) y / 31.0;
4467 float b_f = (float) z / 31.0;
4469 if(fmt == D3DFMT_A16B16G16R16) {
4470 unsigned short *mem_s = mem;
4471 mem_s[0] = r_f * 65535.0;
4472 mem_s[1] = g_f * 65535.0;
4473 mem_s[2] = b_f * 65535.0;
4474 mem_s[3] = 65535;
4475 } else {
4476 unsigned char *mem_c = mem;
4477 mem_c[0] = b_f * 255.0;
4478 mem_c[1] = g_f * 255.0;
4479 mem_c[2] = r_f * 255.0;
4480 mem_c[3] = 255;
4485 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4486 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4488 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4489 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4491 hr = IDirect3DDevice9_BeginScene(device);
4492 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4493 if(SUCCEEDED(hr))
4495 float quad1[] = {
4496 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4497 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4498 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4499 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4501 float quad2[] = {
4502 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4503 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4504 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4505 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4507 float quad3[] = {
4508 0.0, 0.0, 0.1, 0.0, 0.0,
4509 0.0, 1.0, 0.1, 0.0, 0.0,
4510 1.0, 0.0, 0.1, 0.0, 0.0,
4511 1.0, 1.0, 0.1, 0.0, 0.0
4513 float quad4[] = {
4514 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4515 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4516 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4517 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4519 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4520 0.0, 0.0, 1.0, 0.0,
4521 0.0, 1.0, 0.0, 0.0,
4522 0.0, 0.0, 0.0, 1.0};
4523 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4524 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4526 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4527 * values
4529 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4531 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4532 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4534 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4536 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4537 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4538 * otherwise the w will be missing(blue).
4539 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4540 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4541 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4542 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4544 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4546 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4547 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4548 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4549 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4550 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4551 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4553 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4554 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4556 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4557 * disable. ATI extends it up to the amount of values needed for the volume texture
4559 memset(mat, 0, sizeof(mat));
4560 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4561 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4562 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4563 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4564 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4565 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4567 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4569 hr = IDirect3DDevice9_EndScene(device);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4573 color = getPixelColor(device, 160, 360);
4574 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4575 color = getPixelColor(device, 160, 120);
4576 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4577 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4578 color = getPixelColor(device, 480, 120);
4579 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4580 color = getPixelColor(device, 480, 360);
4581 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4583 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4587 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4588 hr = IDirect3DDevice9_BeginScene(device);
4589 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4590 if(SUCCEEDED(hr))
4592 float quad1[] = {
4593 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4594 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4595 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4596 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4598 float quad2[] = {
4599 -1.0, 0.0, 0.1,
4600 -1.0, 1.0, 0.1,
4601 0.0, 0.0, 0.1,
4602 0.0, 1.0, 0.1,
4604 float quad3[] = {
4605 0.0, 0.0, 0.1, 1.0,
4606 0.0, 1.0, 0.1, 1.0,
4607 1.0, 0.0, 0.1, 1.0,
4608 1.0, 1.0, 0.1, 1.0
4610 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4611 0.0, 0.0, 0.0, 0.0,
4612 0.0, 0.0, 0.0, 0.0,
4613 0.0, 1.0, 0.0, 0.0};
4614 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4615 1.0, 0.0, 0.0, 0.0,
4616 0.0, 1.0, 0.0, 0.0,
4617 0.0, 0.0, 1.0, 0.0};
4618 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4619 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4621 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4622 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4623 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4624 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4625 * 4th *input* coordinate.
4627 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4628 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4629 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4630 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4632 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4634 /* None passed */
4635 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4637 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4638 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4640 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4642 /* 4 used, 1 passed */
4643 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4644 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4645 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4648 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4650 hr = IDirect3DDevice9_EndScene(device);
4651 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4653 color = getPixelColor(device, 160, 360);
4654 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4655 color = getPixelColor(device, 160, 120);
4656 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4657 color = getPixelColor(device, 480, 120);
4658 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4659 /* Quad4: unused */
4661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4662 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4664 IDirect3DVolumeTexture9_Release(volume);
4666 out:
4667 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4668 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4669 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4670 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4671 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4672 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4673 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4675 IDirect3DVertexDeclaration9_Release(decl);
4676 IDirect3DVertexDeclaration9_Release(decl2);
4677 IDirect3DVertexDeclaration9_Release(decl3);
4678 IDirect3DVertexDeclaration9_Release(decl4);
4681 static void texdepth_test(IDirect3DDevice9 *device)
4683 IDirect3DPixelShader9 *shader;
4684 HRESULT hr;
4685 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4686 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4687 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4688 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4689 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4690 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4691 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4692 static const DWORD shader_code[] =
4694 0xffff0104, /* ps_1_4 */
4695 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4696 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4697 0x0000fffd, /* phase */
4698 0x00000057, 0x800f0005, /* texdepth r5 */
4699 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4700 0x0000ffff /* end */
4702 DWORD color;
4703 float vertex[] = {
4704 -1.0, -1.0, 0.0,
4705 1.0, -1.0, 1.0,
4706 -1.0, 1.0, 0.0,
4707 1.0, 1.0, 1.0
4710 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4711 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4713 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4714 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4716 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4718 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4720 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4721 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4722 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4724 /* Fill the depth buffer with a gradient */
4725 hr = IDirect3DDevice9_BeginScene(device);
4726 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4727 if(SUCCEEDED(hr))
4729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4730 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4731 hr = IDirect3DDevice9_EndScene(device);
4732 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4735 /* Now perform the actual tests. Same geometry, but with the shader */
4736 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4737 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4739 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4740 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4741 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4743 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4744 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4745 hr = IDirect3DDevice9_BeginScene(device);
4746 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4747 if(SUCCEEDED(hr))
4749 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4750 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4752 hr = IDirect3DDevice9_EndScene(device);
4753 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4756 color = getPixelColor(device, 158, 240);
4757 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4758 color = getPixelColor(device, 162, 240);
4759 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4761 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4764 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4765 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4767 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4768 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4769 hr = IDirect3DDevice9_BeginScene(device);
4770 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4771 if(SUCCEEDED(hr))
4773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4774 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4776 hr = IDirect3DDevice9_EndScene(device);
4777 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4780 color = getPixelColor(device, 318, 240);
4781 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4782 color = getPixelColor(device, 322, 240);
4783 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4785 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4786 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4788 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4789 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4791 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4792 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4793 hr = IDirect3DDevice9_BeginScene(device);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4795 if(SUCCEEDED(hr))
4797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4798 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4800 hr = IDirect3DDevice9_EndScene(device);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4804 color = getPixelColor(device, 1, 240);
4805 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4807 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4811 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4813 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4815 hr = IDirect3DDevice9_BeginScene(device);
4816 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4817 if(SUCCEEDED(hr))
4819 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4820 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4822 hr = IDirect3DDevice9_EndScene(device);
4823 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4825 color = getPixelColor(device, 318, 240);
4826 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4827 color = getPixelColor(device, 322, 240);
4828 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4831 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4834 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4836 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4838 hr = IDirect3DDevice9_BeginScene(device);
4839 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4840 if(SUCCEEDED(hr))
4842 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4843 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4845 hr = IDirect3DDevice9_EndScene(device);
4846 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4849 color = getPixelColor(device, 1, 240);
4850 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4853 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4856 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4858 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4860 hr = IDirect3DDevice9_BeginScene(device);
4861 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4862 if(SUCCEEDED(hr))
4864 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4865 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4867 hr = IDirect3DDevice9_EndScene(device);
4868 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4871 color = getPixelColor(device, 638, 240);
4872 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4874 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4875 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4877 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4878 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4880 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4882 hr = IDirect3DDevice9_BeginScene(device);
4883 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4884 if(SUCCEEDED(hr))
4886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4887 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4889 hr = IDirect3DDevice9_EndScene(device);
4890 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4893 color = getPixelColor(device, 638, 240);
4894 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4896 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4897 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4899 /* Cleanup */
4900 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4901 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4902 IDirect3DPixelShader9_Release(shader);
4904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4905 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4907 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4910 static void texkill_test(IDirect3DDevice9 *device)
4912 IDirect3DPixelShader9 *shader;
4913 HRESULT hr;
4914 DWORD color;
4916 const float vertex[] = {
4917 /* bottom top right left */
4918 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4919 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4920 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4921 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4924 static const DWORD shader_code_11[] =
4926 0xffff0101, /* ps_1_1 */
4927 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4928 0x00000041, 0xb00f0000, /* texkill t0 */
4929 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4930 0x0000ffff /* end */
4932 static const DWORD shader_code_20[] =
4934 0xffff0200, /* ps_2_0 */
4935 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4936 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4937 0x01000041, 0xb00f0000, /* texkill t0 */
4938 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4939 0x0000ffff /* end */
4942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4944 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4945 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4947 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4949 hr = IDirect3DDevice9_BeginScene(device);
4950 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4951 if(SUCCEEDED(hr))
4953 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4954 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4956 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4957 hr = IDirect3DDevice9_EndScene(device);
4958 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4960 color = getPixelColor(device, 63, 46);
4961 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4962 color = getPixelColor(device, 66, 46);
4963 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4964 color = getPixelColor(device, 63, 49);
4965 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4966 color = getPixelColor(device, 66, 49);
4967 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4969 color = getPixelColor(device, 578, 46);
4970 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4971 color = getPixelColor(device, 575, 46);
4972 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4973 color = getPixelColor(device, 578, 49);
4974 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4975 color = getPixelColor(device, 575, 49);
4976 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4978 color = getPixelColor(device, 63, 430);
4979 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4980 color = getPixelColor(device, 63, 433);
4981 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4982 color = getPixelColor(device, 66, 433);
4983 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4984 color = getPixelColor(device, 66, 430);
4985 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4987 color = getPixelColor(device, 578, 430);
4988 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4989 color = getPixelColor(device, 578, 433);
4990 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4991 color = getPixelColor(device, 575, 433);
4992 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4993 color = getPixelColor(device, 575, 430);
4994 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4999 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5001 IDirect3DPixelShader9_Release(shader);
5003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5004 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5005 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
5006 if(FAILED(hr)) {
5007 skip("Failed to create 2.0 test shader, most likely not supported\n");
5008 return;
5011 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5012 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5013 hr = IDirect3DDevice9_BeginScene(device);
5014 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5015 if(SUCCEEDED(hr))
5017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5018 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5019 hr = IDirect3DDevice9_EndScene(device);
5020 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5023 color = getPixelColor(device, 63, 46);
5024 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5025 color = getPixelColor(device, 66, 46);
5026 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5027 color = getPixelColor(device, 63, 49);
5028 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5029 color = getPixelColor(device, 66, 49);
5030 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5032 color = getPixelColor(device, 578, 46);
5033 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5034 color = getPixelColor(device, 575, 46);
5035 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5036 color = getPixelColor(device, 578, 49);
5037 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5038 color = getPixelColor(device, 575, 49);
5039 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5041 color = getPixelColor(device, 63, 430);
5042 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5043 color = getPixelColor(device, 63, 433);
5044 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5045 color = getPixelColor(device, 66, 433);
5046 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5047 color = getPixelColor(device, 66, 430);
5048 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5050 color = getPixelColor(device, 578, 430);
5051 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5052 color = getPixelColor(device, 578, 433);
5053 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5054 color = getPixelColor(device, 575, 433);
5055 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5056 color = getPixelColor(device, 575, 430);
5057 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5059 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5060 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5062 /* Cleanup */
5063 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5064 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5065 IDirect3DPixelShader9_Release(shader);
5068 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5070 IDirect3D9 *d3d9;
5071 HRESULT hr;
5072 IDirect3DTexture9 *texture;
5073 IDirect3DPixelShader9 *shader;
5074 IDirect3DPixelShader9 *shader2;
5075 D3DLOCKED_RECT lr;
5076 DWORD color;
5077 static const DWORD shader_code[] =
5079 0xffff0101, /* ps_1_1 */
5080 0x00000042, 0xb00f0000, /* tex t0 */
5081 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5082 0x0000ffff /* end */
5084 static const DWORD shader_code2[] =
5086 0xffff0101, /* ps_1_1 */
5087 0x00000042, 0xb00f0000, /* tex t0 */
5088 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
5089 0x0000ffff /* end */
5092 float quad[] = {
5093 -1.0, -1.0, 0.1, 0.5, 0.5,
5094 1.0, -1.0, 0.1, 0.5, 0.5,
5095 -1.0, 1.0, 0.1, 0.5, 0.5,
5096 1.0, 1.0, 0.1, 0.5, 0.5,
5099 memset(&lr, 0, sizeof(lr));
5100 IDirect3DDevice9_GetDirect3D(device, &d3d9);
5101 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5102 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5103 IDirect3D9_Release(d3d9);
5104 if(FAILED(hr)) {
5105 skip("No D3DFMT_X8L8V8U8 support\n");
5106 return;
5109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5112 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5113 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5114 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5115 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5116 *((DWORD *) lr.pBits) = 0x11ca3141;
5117 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5118 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5120 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5122 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5123 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5125 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5126 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5127 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5128 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5129 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5130 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5132 hr = IDirect3DDevice9_BeginScene(device);
5133 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5134 if(SUCCEEDED(hr))
5136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5137 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5139 hr = IDirect3DDevice9_EndScene(device);
5140 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5142 color = getPixelColor(device, 578, 430);
5143 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5144 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5145 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5146 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5148 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5149 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5150 hr = IDirect3DDevice9_BeginScene(device);
5151 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5152 if(SUCCEEDED(hr))
5154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5155 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5157 hr = IDirect3DDevice9_EndScene(device);
5158 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5160 color = getPixelColor(device, 578, 430);
5161 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5162 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5163 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5165 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5166 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5167 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5168 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5169 IDirect3DPixelShader9_Release(shader);
5170 IDirect3DPixelShader9_Release(shader2);
5171 IDirect3DTexture9_Release(texture);
5174 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5176 HRESULT hr;
5177 IDirect3D9 *d3d;
5178 IDirect3DTexture9 *texture = NULL;
5179 IDirect3DSurface9 *surface;
5180 DWORD color;
5181 const RECT r1 = {256, 256, 512, 512};
5182 const RECT r2 = {512, 256, 768, 512};
5183 const RECT r3 = {256, 512, 512, 768};
5184 const RECT r4 = {512, 512, 768, 768};
5185 unsigned int x, y;
5186 D3DLOCKED_RECT lr;
5187 memset(&lr, 0, sizeof(lr));
5189 IDirect3DDevice9_GetDirect3D(device, &d3d);
5190 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5191 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5192 skip("No autogenmipmap support\n");
5193 IDirect3D9_Release(d3d);
5194 return;
5196 IDirect3D9_Release(d3d);
5198 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5199 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5201 /* Make the mipmap big, so that a smaller mipmap is used
5203 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5204 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5205 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5207 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5208 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5209 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5210 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5211 for(y = 0; y < 1024; y++) {
5212 for(x = 0; x < 1024; x++) {
5213 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5214 POINT pt;
5216 pt.x = x;
5217 pt.y = y;
5218 if(PtInRect(&r1, pt)) {
5219 *dst = 0xffff0000;
5220 } else if(PtInRect(&r2, pt)) {
5221 *dst = 0xff00ff00;
5222 } else if(PtInRect(&r3, pt)) {
5223 *dst = 0xff0000ff;
5224 } else if(PtInRect(&r4, pt)) {
5225 *dst = 0xff000000;
5226 } else {
5227 *dst = 0xffffffff;
5231 hr = IDirect3DSurface9_UnlockRect(surface);
5232 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5233 IDirect3DSurface9_Release(surface);
5235 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5236 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5238 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5240 hr = IDirect3DDevice9_BeginScene(device);
5241 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5242 if(SUCCEEDED(hr)) {
5243 const float quad[] = {
5244 -0.5, -0.5, 0.1, 0.0, 0.0,
5245 -0.5, 0.5, 0.1, 0.0, 1.0,
5246 0.5, -0.5, 0.1, 1.0, 0.0,
5247 0.5, 0.5, 0.1, 1.0, 1.0
5250 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5251 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5252 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5253 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5254 hr = IDirect3DDevice9_EndScene(device);
5255 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5257 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5258 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5259 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5260 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5261 IDirect3DTexture9_Release(texture);
5263 color = getPixelColor(device, 200, 200);
5264 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5265 color = getPixelColor(device, 280, 200);
5266 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5267 color = getPixelColor(device, 360, 200);
5268 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5269 color = getPixelColor(device, 440, 200);
5270 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5271 color = getPixelColor(device, 200, 270);
5272 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5273 color = getPixelColor(device, 280, 270);
5274 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5275 color = getPixelColor(device, 360, 270);
5276 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5277 color = getPixelColor(device, 440, 270);
5278 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5279 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5280 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5283 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5285 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5286 IDirect3DVertexDeclaration9 *decl;
5287 HRESULT hr;
5288 DWORD color;
5289 static const DWORD shader_code_11[] =
5291 0xfffe0101, /* vs_1_1 */
5292 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5293 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5294 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5295 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5296 0x0000ffff /* end */
5298 static const DWORD shader_code_11_2[] =
5300 0xfffe0101, /* vs_1_1 */
5301 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5302 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5303 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5304 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5305 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5306 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5307 0x0000ffff /* end */
5309 static const DWORD shader_code_20[] =
5311 0xfffe0200, /* vs_2_0 */
5312 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5313 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5314 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5315 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5316 0x0000ffff /* end */
5318 static const DWORD shader_code_20_2[] =
5320 0xfffe0200, /* vs_2_0 */
5321 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5322 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5323 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5324 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5325 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5326 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5327 0x0000ffff /* end */
5329 static const D3DVERTEXELEMENT9 decl_elements[] = {
5330 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5331 D3DDECL_END()
5333 float quad1[] = {
5334 -1.0, -1.0, 0.1,
5335 0.0, -1.0, 0.1,
5336 -1.0, 0.0, 0.1,
5337 0.0, 0.0, 0.1
5339 float quad2[] = {
5340 0.0, -1.0, 0.1,
5341 1.0, -1.0, 0.1,
5342 0.0, 0.0, 0.1,
5343 1.0, 0.0, 0.1
5345 float quad3[] = {
5346 0.0, 0.0, 0.1,
5347 1.0, 0.0, 0.1,
5348 0.0, 1.0, 0.1,
5349 1.0, 1.0, 0.1
5351 float quad4[] = {
5352 -1.0, 0.0, 0.1,
5353 0.0, 0.0, 0.1,
5354 -1.0, 1.0, 0.1,
5355 0.0, 1.0, 0.1
5357 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5358 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5361 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5363 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5364 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5365 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5366 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5367 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5368 if(FAILED(hr)) shader_20 = NULL;
5369 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5370 if(FAILED(hr)) shader_20_2 = NULL;
5371 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5372 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5374 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5375 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5376 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5377 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5378 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5379 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5381 hr = IDirect3DDevice9_BeginScene(device);
5382 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5383 if(SUCCEEDED(hr))
5385 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5386 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5388 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5390 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5391 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5393 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5395 if(shader_20) {
5396 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5397 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5399 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5402 if(shader_20_2) {
5403 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5404 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5406 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5409 hr = IDirect3DDevice9_EndScene(device);
5410 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5413 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5414 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5415 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5418 color = getPixelColor(device, 160, 360);
5419 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5420 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5421 color = getPixelColor(device, 480, 360);
5422 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5423 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5424 if(shader_20) {
5425 color = getPixelColor(device, 480, 120);
5426 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5427 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5429 if(shader_20_2) {
5430 color = getPixelColor(device, 160, 120);
5431 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5432 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5434 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5435 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5437 IDirect3DVertexDeclaration9_Release(decl);
5438 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5439 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5440 IDirect3DVertexShader9_Release(shader_11_2);
5441 IDirect3DVertexShader9_Release(shader_11);
5444 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5446 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5447 HRESULT hr;
5448 DWORD color;
5449 static const DWORD shader_code_11[] =
5451 0xffff0101, /* ps_1_1 */
5452 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5453 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5454 0x0000ffff /* end */
5456 static const DWORD shader_code_12[] =
5458 0xffff0102, /* ps_1_2 */
5459 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5460 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5461 0x0000ffff /* end */
5463 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
5464 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
5465 * unlikely that 1.3 shaders are different. During development of this
5466 * test, 1.3 shaders were verified too. */
5467 static const DWORD shader_code_14[] =
5469 0xffff0104, /* ps_1_4 */
5470 /* Try to make one constant local. It gets clamped too, although the
5471 * binary contains the bigger numbers. */
5472 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5473 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5474 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5475 0x0000ffff /* end */
5477 static const DWORD shader_code_20[] =
5479 0xffff0200, /* ps_2_0 */
5480 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5481 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5482 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5483 0x0000ffff /* end */
5485 float quad1[] = {
5486 -1.0, -1.0, 0.1,
5487 0.0, -1.0, 0.1,
5488 -1.0, 0.0, 0.1,
5489 0.0, 0.0, 0.1
5491 float quad2[] = {
5492 0.0, -1.0, 0.1,
5493 1.0, -1.0, 0.1,
5494 0.0, 0.0, 0.1,
5495 1.0, 0.0, 0.1
5497 float quad3[] = {
5498 0.0, 0.0, 0.1,
5499 1.0, 0.0, 0.1,
5500 0.0, 1.0, 0.1,
5501 1.0, 1.0, 0.1
5503 float quad4[] = {
5504 -1.0, 0.0, 0.1,
5505 0.0, 0.0, 0.1,
5506 -1.0, 1.0, 0.1,
5507 0.0, 1.0, 0.1
5509 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5510 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5513 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5515 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5516 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5517 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5519 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5521 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5522 if(FAILED(hr)) shader_20 = NULL;
5524 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5526 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5528 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5529 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5531 hr = IDirect3DDevice9_BeginScene(device);
5532 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5533 if(SUCCEEDED(hr))
5535 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5536 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5537 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5538 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5540 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5541 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5543 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5545 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5548 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5550 if(shader_20) {
5551 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5552 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5553 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5554 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5557 hr = IDirect3DDevice9_EndScene(device);
5558 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5560 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5561 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5563 color = getPixelColor(device, 160, 360);
5564 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5565 "quad 1 has color %08x, expected 0x00808000\n", color);
5566 color = getPixelColor(device, 480, 360);
5567 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5568 "quad 2 has color %08x, expected 0x00808000\n", color);
5569 color = getPixelColor(device, 480, 120);
5570 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5571 "quad 3 has color %08x, expected 0x00808000\n", color);
5572 if(shader_20) {
5573 color = getPixelColor(device, 160, 120);
5574 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5575 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5577 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5578 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5580 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5581 IDirect3DPixelShader9_Release(shader_14);
5582 IDirect3DPixelShader9_Release(shader_12);
5583 IDirect3DPixelShader9_Release(shader_11);
5586 static void dp2add_ps_test(IDirect3DDevice9 *device)
5588 IDirect3DPixelShader9 *shader_dp2add = NULL;
5589 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5590 HRESULT hr;
5591 DWORD color;
5593 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5594 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5595 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5596 * r0 first.
5597 * The result here for the r,g,b components should be roughly 0.5:
5598 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5599 static const DWORD shader_code_dp2add[] = {
5600 0xffff0200, /* ps_2_0 */
5601 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5603 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5604 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5606 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5607 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5608 0x0000ffff /* end */
5611 /* Test the _sat modifier, too. Result here should be:
5612 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5613 * _SAT: ==> 1.0
5614 * ADD: (1.0 + -0.5) = 0.5
5616 static const DWORD shader_code_dp2add_sat[] = {
5617 0xffff0200, /* ps_2_0 */
5618 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5620 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5621 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5622 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5624 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5625 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5626 0x0000ffff /* end */
5629 const float quad[] = {
5630 -1.0, -1.0, 0.1,
5631 1.0, -1.0, 0.1,
5632 -1.0, 1.0, 0.1,
5633 1.0, 1.0, 0.1
5637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5638 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5640 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5641 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5643 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5644 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5646 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5647 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5649 if (shader_dp2add) {
5651 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5652 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5654 hr = IDirect3DDevice9_BeginScene(device);
5655 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5656 if(SUCCEEDED(hr))
5658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5659 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5661 hr = IDirect3DDevice9_EndScene(device);
5662 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5665 color = getPixelColor(device, 360, 240);
5666 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5667 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5669 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5670 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5672 IDirect3DPixelShader9_Release(shader_dp2add);
5673 } else {
5674 skip("dp2add shader creation failed\n");
5677 if (shader_dp2add_sat) {
5679 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5680 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5682 hr = IDirect3DDevice9_BeginScene(device);
5683 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5684 if(SUCCEEDED(hr))
5686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5687 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5689 hr = IDirect3DDevice9_EndScene(device);
5690 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5693 color = getPixelColor(device, 360, 240);
5694 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5695 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5697 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5698 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5700 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5701 } else {
5702 skip("dp2add shader creation failed\n");
5705 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5706 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5709 static void cnd_test(IDirect3DDevice9 *device)
5711 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5712 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5713 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
5714 HRESULT hr;
5715 DWORD color;
5716 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
5717 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
5718 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
5719 * in 1.x pixel shaders. */
5720 static const DWORD shader_code_11[] =
5722 0xffff0101, /* ps_1_1 */
5723 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5724 0x00000040, 0xb00f0000, /* texcoord t0 */
5725 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5726 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5727 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5728 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5729 0x0000ffff /* end */
5731 static const DWORD shader_code_12[] =
5733 0xffff0102, /* ps_1_2 */
5734 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5735 0x00000040, 0xb00f0000, /* texcoord t0 */
5736 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5737 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5738 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5739 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5740 0x0000ffff /* end */
5742 static const DWORD shader_code_13[] =
5744 0xffff0103, /* ps_1_3 */
5745 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5746 0x00000040, 0xb00f0000, /* texcoord t0 */
5747 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5748 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5749 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5750 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5751 0x0000ffff /* end */
5753 static const DWORD shader_code_14[] =
5755 0xffff0104, /* ps_1_3 */
5756 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5757 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5758 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5759 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5760 0x0000ffff /* end */
5763 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5764 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5765 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5766 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5767 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5768 * well enough.
5770 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5771 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5772 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5773 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5775 static const DWORD shader_code_11_coissue[] =
5777 0xffff0101, /* ps_1_1 */
5778 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5779 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5780 0x00000040, 0xb00f0000, /* texcoord t0 */
5781 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5782 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5783 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5784 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5785 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5786 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
5787 0x0000ffff /* end */
5789 static const DWORD shader_code_11_coissue_2[] =
5791 0xffff0101, /* ps_1_1 */
5792 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5793 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5794 0x00000040, 0xb00f0000, /* texcoord t0 */
5795 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5796 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5797 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5798 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5799 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
5800 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
5801 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
5802 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
5803 0x0000ffff /* end */
5805 static const DWORD shader_code_12_coissue[] =
5807 0xffff0102, /* ps_1_2 */
5808 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5809 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5810 0x00000040, 0xb00f0000, /* texcoord t0 */
5811 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5812 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5813 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5814 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5815 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5816 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
5817 0x0000ffff /* end */
5819 static const DWORD shader_code_12_coissue_2[] =
5821 0xffff0102, /* ps_1_2 */
5822 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5823 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5824 0x00000040, 0xb00f0000, /* texcoord t0 */
5825 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5826 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5827 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5828 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5829 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
5830 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
5831 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
5832 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
5833 0x0000ffff /* end */
5835 static const DWORD shader_code_13_coissue[] =
5837 0xffff0103, /* ps_1_3 */
5838 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5839 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5840 0x00000040, 0xb00f0000, /* texcoord t0 */
5841 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5842 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5843 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5844 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5845 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5846 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
5847 0x0000ffff /* end */
5849 static const DWORD shader_code_13_coissue_2[] =
5851 0xffff0103, /* ps_1_3 */
5852 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5853 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5854 0x00000040, 0xb00f0000, /* texcoord t0 */
5855 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5856 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5857 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5858 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5859 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
5860 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
5861 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
5862 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
5863 0x0000ffff /* end */
5865 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
5866 * texcrd result to cnd, it will compare against 0.5. */
5867 static const DWORD shader_code_14_coissue[] =
5869 0xffff0104, /* ps_1_4 */
5870 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5871 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
5872 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5873 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
5874 0x0000ffff /* end */
5876 static const DWORD shader_code_14_coissue_2[] =
5878 0xffff0104, /* ps_1_4 */
5879 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5880 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
5881 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
5882 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
5883 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
5884 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
5885 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5886 0x0000ffff /* end */
5888 float quad1[] = {
5889 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5890 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5891 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5892 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5894 float quad2[] = {
5895 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5896 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5897 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5898 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5900 float quad3[] = {
5901 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5902 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5903 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5904 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5906 float quad4[] = {
5907 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5908 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5909 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5910 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5912 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5913 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5914 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5915 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5917 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5918 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5920 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5921 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5922 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5923 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5924 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5925 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5926 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5927 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5928 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5929 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5930 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5931 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5932 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5933 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5934 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5935 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5936 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
5937 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5938 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
5939 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5940 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
5941 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5942 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
5943 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5945 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5946 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5947 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5948 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5949 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5950 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5952 hr = IDirect3DDevice9_BeginScene(device);
5953 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5954 if(SUCCEEDED(hr))
5956 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5957 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5959 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5961 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5962 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5964 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5966 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5967 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5969 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5971 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5972 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5974 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5976 hr = IDirect3DDevice9_EndScene(device);
5977 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5980 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5981 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5983 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5984 color = getPixelColor(device, 158, 118);
5985 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5986 color = getPixelColor(device, 162, 118);
5987 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5988 color = getPixelColor(device, 158, 122);
5989 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5990 color = getPixelColor(device, 162, 122);
5991 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5993 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5994 color = getPixelColor(device, 158, 358);
5995 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5996 color = getPixelColor(device, 162, 358);
5997 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5998 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5999 color = getPixelColor(device, 158, 362);
6000 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6001 color = getPixelColor(device, 162, 362);
6002 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
6003 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
6005 /* 1.2 shader */
6006 color = getPixelColor(device, 478, 358);
6007 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6008 color = getPixelColor(device, 482, 358);
6009 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
6010 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
6011 color = getPixelColor(device, 478, 362);
6012 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6013 color = getPixelColor(device, 482, 362);
6014 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
6015 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
6017 /* 1.3 shader */
6018 color = getPixelColor(device, 478, 118);
6019 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6020 color = getPixelColor(device, 482, 118);
6021 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
6022 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
6023 color = getPixelColor(device, 478, 122);
6024 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6025 color = getPixelColor(device, 482, 122);
6026 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
6027 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
6029 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6030 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6034 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6036 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6037 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6039 hr = IDirect3DDevice9_BeginScene(device);
6040 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6041 if(SUCCEEDED(hr))
6043 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6044 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6045 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6046 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6048 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6049 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6051 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6053 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6054 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6056 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6058 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6059 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6061 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6063 hr = IDirect3DDevice9_EndScene(device);
6064 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6067 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6068 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6070 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6071 * that we swapped the values in c1 and c2 to make the other tests return some color
6073 color = getPixelColor(device, 158, 118);
6074 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6075 color = getPixelColor(device, 162, 118);
6076 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6077 color = getPixelColor(device, 158, 122);
6078 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6079 color = getPixelColor(device, 162, 122);
6080 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6082 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6083 * (The Win7 nvidia driver always selects c2)
6085 color = getPixelColor(device, 158, 358);
6086 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6087 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6088 color = getPixelColor(device, 162, 358);
6089 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6090 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6091 color = getPixelColor(device, 158, 362);
6092 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6093 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6094 color = getPixelColor(device, 162, 362);
6095 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6096 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6098 /* 1.2 shader */
6099 color = getPixelColor(device, 478, 358);
6100 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6101 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6102 color = getPixelColor(device, 482, 358);
6103 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6104 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6105 color = getPixelColor(device, 478, 362);
6106 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6107 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6108 color = getPixelColor(device, 482, 362);
6109 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6110 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6112 /* 1.3 shader */
6113 color = getPixelColor(device, 478, 118);
6114 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6115 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6116 color = getPixelColor(device, 482, 118);
6117 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6118 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6119 color = getPixelColor(device, 478, 122);
6120 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6121 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6122 color = getPixelColor(device, 482, 122);
6123 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6124 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6127 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6129 /* Retest with the coissue flag on the alpha instruction instead. This works "as expected". */
6130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6131 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6133 hr = IDirect3DDevice9_BeginScene(device);
6134 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6135 if(SUCCEEDED(hr))
6137 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6138 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6140 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6142 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6143 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6145 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6147 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6148 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6150 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6152 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6153 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6155 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6157 hr = IDirect3DDevice9_EndScene(device);
6158 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6161 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6162 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6164 /* 1.4 shader */
6165 color = getPixelColor(device, 158, 118);
6166 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6167 color = getPixelColor(device, 162, 118);
6168 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6169 color = getPixelColor(device, 158, 122);
6170 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6171 color = getPixelColor(device, 162, 122);
6172 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6174 /* 1.1 shader */
6175 color = getPixelColor(device, 238, 358);
6176 ok(color_match(color, 0x00ffffff, 1),
6177 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6178 color = getPixelColor(device, 242, 358);
6179 ok(color_match(color, 0x00000000, 1),
6180 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6181 color = getPixelColor(device, 238, 362);
6182 ok(color_match(color, 0x00ffffff, 1),
6183 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6184 color = getPixelColor(device, 242, 362);
6185 ok(color_match(color, 0x00000000, 1),
6186 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6188 /* 1.2 shader */
6189 color = getPixelColor(device, 558, 358);
6190 ok(color_match(color, 0x00ffffff, 1),
6191 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6192 color = getPixelColor(device, 562, 358);
6193 ok(color_match(color, 0x00000000, 1),
6194 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6195 color = getPixelColor(device, 558, 362);
6196 ok(color_match(color, 0x00ffffff, 1),
6197 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6198 color = getPixelColor(device, 562, 362);
6199 ok(color_match(color, 0x00000000, 1),
6200 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6202 /* 1.3 shader */
6203 color = getPixelColor(device, 558, 118);
6204 ok(color_match(color, 0x00ffffff, 1),
6205 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6206 color = getPixelColor(device, 562, 118);
6207 ok(color_match(color, 0x00000000, 1),
6208 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6209 color = getPixelColor(device, 558, 122);
6210 ok(color_match(color, 0x00ffffff, 1),
6211 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6212 color = getPixelColor(device, 562, 122);
6213 ok(color_match(color, 0x00000000, 1),
6214 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6216 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6217 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6219 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6220 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6221 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6222 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6223 IDirect3DPixelShader9_Release(shader_14_coissue);
6224 IDirect3DPixelShader9_Release(shader_13_coissue);
6225 IDirect3DPixelShader9_Release(shader_12_coissue);
6226 IDirect3DPixelShader9_Release(shader_11_coissue);
6227 IDirect3DPixelShader9_Release(shader_14);
6228 IDirect3DPixelShader9_Release(shader_13);
6229 IDirect3DPixelShader9_Release(shader_12);
6230 IDirect3DPixelShader9_Release(shader_11);
6233 static void nested_loop_test(IDirect3DDevice9 *device)
6235 static const DWORD shader_code[] =
6237 0xffff0300, /* ps_3_0 */
6238 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6239 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6240 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
6241 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6242 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6243 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6244 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6245 0x0000001d, /* endloop */
6246 0x0000001d, /* endloop */
6247 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6248 0x0000ffff /* end */
6250 static const DWORD vshader_code[] =
6252 0xfffe0300, /* vs_3_0 */
6253 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6254 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6255 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6256 0x0000ffff /* end */
6258 IDirect3DPixelShader9 *shader;
6259 IDirect3DVertexShader9 *vshader;
6260 HRESULT hr;
6261 DWORD color;
6262 const float quad[] = {
6263 -1.0, -1.0, 0.1,
6264 1.0, -1.0, 0.1,
6265 -1.0, 1.0, 0.1,
6266 1.0, 1.0, 0.1
6269 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6270 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6271 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6272 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6273 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6274 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6275 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6276 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6277 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6278 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6280 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6282 hr = IDirect3DDevice9_BeginScene(device);
6283 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6284 if(SUCCEEDED(hr))
6286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6287 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6288 hr = IDirect3DDevice9_EndScene(device);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6292 color = getPixelColor(device, 360, 240);
6293 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6294 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6297 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6299 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6301 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6303 IDirect3DPixelShader9_Release(shader);
6304 IDirect3DVertexShader9_Release(vshader);
6307 struct varying_test_struct
6309 const DWORD *shader_code;
6310 IDirect3DPixelShader9 *shader;
6311 DWORD color, color_rhw;
6312 const char *name;
6313 BOOL todo, todo_rhw;
6316 struct hugeVertex
6318 float pos_x, pos_y, pos_z, rhw;
6319 float weight_1, weight_2, weight_3, weight_4;
6320 float index_1, index_2, index_3, index_4;
6321 float normal_1, normal_2, normal_3, normal_4;
6322 float fog_1, fog_2, fog_3, fog_4;
6323 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
6324 float tangent_1, tangent_2, tangent_3, tangent_4;
6325 float binormal_1, binormal_2, binormal_3, binormal_4;
6326 float depth_1, depth_2, depth_3, depth_4;
6327 DWORD diffuse, specular;
6330 static void pretransformed_varying_test(IDirect3DDevice9 *device)
6332 /* dcl_position: fails to compile */
6333 static const DWORD blendweight_code[] =
6335 0xffff0300, /* ps_3_0 */
6336 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6337 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6338 0x0000ffff /* end */
6340 static const DWORD blendindices_code[] =
6342 0xffff0300, /* ps_3_0 */
6343 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6344 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6345 0x0000ffff /* end */
6347 static const DWORD normal_code[] =
6349 0xffff0300, /* ps_3_0 */
6350 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6351 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6352 0x0000ffff /* end */
6354 /* psize: fails? */
6355 static const DWORD texcoord0_code[] =
6357 0xffff0300, /* ps_3_0 */
6358 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6359 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6360 0x0000ffff /* end */
6362 static const DWORD tangent_code[] =
6364 0xffff0300, /* ps_3_0 */
6365 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6366 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6367 0x0000ffff /* end */
6369 static const DWORD binormal_code[] =
6371 0xffff0300, /* ps_3_0 */
6372 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6373 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6374 0x0000ffff /* end */
6376 /* tessfactor: fails */
6377 /* positiont: fails */
6378 static const DWORD color_code[] =
6380 0xffff0300, /* ps_3_0 */
6381 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6382 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6383 0x0000ffff /* end */
6385 static const DWORD fog_code[] =
6387 0xffff0300, /* ps_3_0 */
6388 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
6389 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6390 0x0000ffff /* end */
6392 static const DWORD depth_code[] =
6394 0xffff0300, /* ps_3_0 */
6395 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
6396 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6397 0x0000ffff /* end */
6399 static const DWORD specular_code[] =
6401 0xffff0300, /* ps_3_0 */
6402 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
6403 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6404 0x0000ffff /* end */
6406 /* sample: fails */
6408 struct varying_test_struct tests[] = {
6409 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
6410 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
6411 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
6412 /* Why does dx not forward the texcoord? */
6413 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
6414 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
6415 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
6416 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
6417 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
6418 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
6419 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
6421 /* Declare a monster vertex type :-) */
6422 static const D3DVERTEXELEMENT9 decl_elements[] = {
6423 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6424 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
6425 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
6426 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
6427 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
6428 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6429 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
6430 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
6431 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
6432 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6433 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
6434 D3DDECL_END()
6436 struct hugeVertex data[4] = {
6438 -1.0, -1.0, 0.1, 1.0,
6439 0.1, 0.1, 0.1, 0.1,
6440 0.2, 0.2, 0.2, 0.2,
6441 0.3, 0.3, 0.3, 0.3,
6442 0.4, 0.4, 0.4, 0.4,
6443 0.50, 0.55, 0.55, 0.55,
6444 0.6, 0.6, 0.6, 0.7,
6445 0.7, 0.7, 0.7, 0.6,
6446 0.8, 0.8, 0.8, 0.8,
6447 0xe6e6e6e6, /* 0.9 * 256 */
6448 0x224488ff /* Nothing special */
6451 1.0, -1.0, 0.1, 1.0,
6452 0.1, 0.1, 0.1, 0.1,
6453 0.2, 0.2, 0.2, 0.2,
6454 0.3, 0.3, 0.3, 0.3,
6455 0.4, 0.4, 0.4, 0.4,
6456 0.50, 0.55, 0.55, 0.55,
6457 0.6, 0.6, 0.6, 0.7,
6458 0.7, 0.7, 0.7, 0.6,
6459 0.8, 0.8, 0.8, 0.8,
6460 0xe6e6e6e6, /* 0.9 * 256 */
6461 0x224488ff /* Nothing special */
6464 -1.0, 1.0, 0.1, 1.0,
6465 0.1, 0.1, 0.1, 0.1,
6466 0.2, 0.2, 0.2, 0.2,
6467 0.3, 0.3, 0.3, 0.3,
6468 0.4, 0.4, 0.4, 0.4,
6469 0.50, 0.55, 0.55, 0.55,
6470 0.6, 0.6, 0.6, 0.7,
6471 0.7, 0.7, 0.7, 0.6,
6472 0.8, 0.8, 0.8, 0.8,
6473 0xe6e6e6e6, /* 0.9 * 256 */
6474 0x224488ff /* Nothing special */
6477 1.0, 1.0, 0.1, 1.0,
6478 0.1, 0.1, 0.1, 0.1,
6479 0.2, 0.2, 0.2, 0.2,
6480 0.3, 0.3, 0.3, 0.3,
6481 0.4, 0.4, 0.4, 0.4,
6482 0.50, 0.55, 0.55, 0.55,
6483 0.6, 0.6, 0.6, 0.7,
6484 0.7, 0.7, 0.7, 0.6,
6485 0.8, 0.8, 0.8, 0.8,
6486 0xe6e6e6e6, /* 0.9 * 256 */
6487 0x224488ff /* Nothing special */
6490 struct hugeVertex data2[4];
6491 IDirect3DVertexDeclaration9 *decl;
6492 HRESULT hr;
6493 unsigned int i;
6494 DWORD color, r, g, b, r_e, g_e, b_e;
6496 memcpy(data2, data, sizeof(data2));
6497 data2[0].pos_x = 0; data2[0].pos_y = 0;
6498 data2[1].pos_x = 640; data2[1].pos_y = 0;
6499 data2[2].pos_x = 0; data2[2].pos_y = 480;
6500 data2[3].pos_x = 640; data2[3].pos_y = 480;
6502 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6503 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6504 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6505 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6507 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6509 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6510 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6511 tests[i].name, hr);
6514 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6515 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6516 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6518 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6519 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6521 hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6522 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6524 hr = IDirect3DDevice9_BeginScene(device);
6525 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6526 if(SUCCEEDED(hr))
6528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6529 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6530 hr = IDirect3DDevice9_EndScene(device);
6531 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6534 color = getPixelColor(device, 360, 240);
6535 r = color & 0x00ff0000 >> 16;
6536 g = color & 0x0000ff00 >> 8;
6537 b = color & 0x000000ff;
6538 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6539 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
6540 b_e = tests[i].color_rhw & 0x000000ff;
6542 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6543 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6545 if(tests[i].todo_rhw) {
6546 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6547 * pipeline
6549 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6550 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6551 tests[i].name, color, tests[i].color_rhw);
6552 } else {
6553 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6554 "Test %s returned color 0x%08x, expected 0x%08x\n",
6555 tests[i].name, color, tests[i].color_rhw);
6559 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6561 IDirect3DPixelShader9_Release(tests[i].shader);
6564 IDirect3DVertexDeclaration9_Release(decl);
6567 static void test_compare_instructions(IDirect3DDevice9 *device)
6569 static const DWORD shader_sge_vec_code[] =
6571 0xfffe0101, /* vs_1_1 */
6572 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6573 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6574 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6575 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6576 0x0000ffff /* end */
6578 static const DWORD shader_slt_vec_code[] =
6580 0xfffe0101, /* vs_1_1 */
6581 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6582 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6583 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6584 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6585 0x0000ffff /* end */
6587 static const DWORD shader_sge_scalar_code[] =
6589 0xfffe0101, /* vs_1_1 */
6590 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6591 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6592 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6593 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6594 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6595 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6596 0x0000ffff /* end */
6598 static const DWORD shader_slt_scalar_code[] =
6600 0xfffe0101, /* vs_1_1 */
6601 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6602 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6603 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6604 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6605 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6606 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6607 0x0000ffff /* end */
6609 IDirect3DVertexShader9 *shader_sge_vec;
6610 IDirect3DVertexShader9 *shader_slt_vec;
6611 IDirect3DVertexShader9 *shader_sge_scalar;
6612 IDirect3DVertexShader9 *shader_slt_scalar;
6613 HRESULT hr, color;
6614 float quad1[] = {
6615 -1.0, -1.0, 0.1,
6616 0.0, -1.0, 0.1,
6617 -1.0, 0.0, 0.1,
6618 0.0, 0.0, 0.1
6620 float quad2[] = {
6621 0.0, -1.0, 0.1,
6622 1.0, -1.0, 0.1,
6623 0.0, 0.0, 0.1,
6624 1.0, 0.0, 0.1
6626 float quad3[] = {
6627 -1.0, 0.0, 0.1,
6628 0.0, 0.0, 0.1,
6629 -1.0, 1.0, 0.1,
6630 0.0, 1.0, 0.1
6632 float quad4[] = {
6633 0.0, 0.0, 0.1,
6634 1.0, 0.0, 0.1,
6635 0.0, 1.0, 0.1,
6636 1.0, 1.0, 0.1
6638 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6639 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6642 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6644 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6645 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6646 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6647 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6648 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6649 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6650 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6651 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6652 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6653 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6654 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6655 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6656 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6657 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6659 hr = IDirect3DDevice9_BeginScene(device);
6660 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6661 if(SUCCEEDED(hr))
6663 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6666 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6668 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6669 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6671 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6673 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6674 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6675 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6676 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6678 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6679 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6681 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6682 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6684 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6686 hr = IDirect3DDevice9_EndScene(device);
6687 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6690 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6693 color = getPixelColor(device, 160, 360);
6694 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
6695 color = getPixelColor(device, 480, 360);
6696 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
6697 color = getPixelColor(device, 160, 120);
6698 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
6699 color = getPixelColor(device, 480, 160);
6700 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6702 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6703 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6705 IDirect3DVertexShader9_Release(shader_sge_vec);
6706 IDirect3DVertexShader9_Release(shader_slt_vec);
6707 IDirect3DVertexShader9_Release(shader_sge_scalar);
6708 IDirect3DVertexShader9_Release(shader_slt_scalar);
6711 static void test_vshader_input(IDirect3DDevice9 *device)
6713 static const DWORD swapped_shader_code_3[] =
6715 0xfffe0300, /* vs_3_0 */
6716 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6717 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6718 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6719 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6720 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6721 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6722 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6723 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6724 0x0000ffff /* end */
6726 static const DWORD swapped_shader_code_1[] =
6728 0xfffe0101, /* vs_1_1 */
6729 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6730 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6731 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6732 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6733 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6734 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6735 0x0000ffff /* end */
6737 static const DWORD swapped_shader_code_2[] =
6739 0xfffe0200, /* vs_2_0 */
6740 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6741 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6742 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6743 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6744 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6745 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6746 0x0000ffff /* end */
6748 static const DWORD texcoord_color_shader_code_3[] =
6750 0xfffe0300, /* vs_3_0 */
6751 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6752 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6753 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6754 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6755 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6756 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6757 0x0000ffff /* end */
6759 static const DWORD texcoord_color_shader_code_2[] =
6761 0xfffe0200, /* vs_2_0 */
6762 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6763 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6764 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6765 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6766 0x0000ffff /* end */
6768 static const DWORD texcoord_color_shader_code_1[] =
6770 0xfffe0101, /* vs_1_1 */
6771 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6772 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6773 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6774 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6775 0x0000ffff /* end */
6777 static const DWORD color_color_shader_code_3[] =
6779 0xfffe0300, /* vs_3_0 */
6780 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6781 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6782 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6783 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6784 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6785 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6786 0x0000ffff /* end */
6788 static const DWORD color_color_shader_code_2[] =
6790 0xfffe0200, /* vs_2_0 */
6791 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6792 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6793 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6794 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6795 0x0000ffff /* end */
6797 static const DWORD color_color_shader_code_1[] =
6799 0xfffe0101, /* vs_1_1 */
6800 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6801 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6802 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6803 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6804 0x0000ffff /* end */
6806 static const DWORD ps3_code[] =
6808 0xffff0300, /* ps_3_0 */
6809 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6810 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6811 0x0000ffff /* end */
6813 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6814 IDirect3DPixelShader9 *ps;
6815 HRESULT hr;
6816 DWORD color;
6817 float quad1[] = {
6818 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6819 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6820 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6821 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6823 float quad2[] = {
6824 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6825 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6826 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6827 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6829 float quad3[] = {
6830 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6831 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6832 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6833 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6835 float quad4[] = {
6836 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6837 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6838 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6839 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6841 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6842 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6843 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6844 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6845 D3DDECL_END()
6847 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6848 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6849 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6850 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6851 D3DDECL_END()
6853 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6854 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6855 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6856 D3DDECL_END()
6858 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6859 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6860 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6861 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6862 D3DDECL_END()
6864 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6865 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6866 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6867 D3DDECL_END()
6869 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6870 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6871 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6872 D3DDECL_END()
6874 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6875 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6876 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6877 D3DDECL_END()
6879 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6880 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6881 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6882 D3DDECL_END()
6884 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6885 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6886 unsigned int i;
6887 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6888 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6890 struct vertex quad1_color[] = {
6891 {-1.0, -1.0, 0.1, 0x00ff8040},
6892 { 0.0, -1.0, 0.1, 0x00ff8040},
6893 {-1.0, 0.0, 0.1, 0x00ff8040},
6894 { 0.0, 0.0, 0.1, 0x00ff8040}
6896 struct vertex quad2_color[] = {
6897 { 0.0, -1.0, 0.1, 0x00ff8040},
6898 { 1.0, -1.0, 0.1, 0x00ff8040},
6899 { 0.0, 0.0, 0.1, 0x00ff8040},
6900 { 1.0, 0.0, 0.1, 0x00ff8040}
6902 struct vertex quad3_color[] = {
6903 {-1.0, 0.0, 0.1, 0x00ff8040},
6904 { 0.0, 0.0, 0.1, 0x00ff8040},
6905 {-1.0, 1.0, 0.1, 0x00ff8040},
6906 { 0.0, 1.0, 0.1, 0x00ff8040}
6908 float quad4_color[] = {
6909 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6910 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6911 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6912 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6915 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6916 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6917 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6918 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6919 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6920 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6921 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6922 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6924 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6925 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6926 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6927 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6928 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6929 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6930 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6931 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6933 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6934 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6936 for(i = 1; i <= 3; i++) {
6937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6938 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6939 if(i == 3) {
6940 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6941 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6942 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6943 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6944 } else if(i == 2){
6945 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6946 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6947 } else if(i == 1) {
6948 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6949 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6952 hr = IDirect3DDevice9_BeginScene(device);
6953 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6954 if(SUCCEEDED(hr))
6956 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6957 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6959 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6960 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6962 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6964 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6967 if(i == 3 || i == 2) {
6968 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6969 } else if(i == 1) {
6970 /* Succeeds or fails, depending on SW or HW vertex processing */
6971 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6974 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6975 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6977 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6979 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6980 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6982 if(i == 3 || i == 2) {
6983 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6984 } else if(i == 1) {
6985 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6988 hr = IDirect3DDevice9_EndScene(device);
6989 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6992 if(i == 3 || i == 2) {
6993 color = getPixelColor(device, 160, 360);
6994 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6995 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
6997 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6998 color = getPixelColor(device, 480, 360);
6999 ok(color == 0x00ffff00 || color ==0x00ff0000,
7000 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00ffff00\n", color);
7001 color = getPixelColor(device, 160, 120);
7002 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7003 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7004 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7006 color = getPixelColor(device, 480, 160);
7007 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7008 } else if(i == 1) {
7009 color = getPixelColor(device, 160, 360);
7010 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7011 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7012 color = getPixelColor(device, 480, 360);
7013 /* Accept the clear color as well in this case, since SW VP returns an error */
7014 ok(color == 0x00ffff00 || color == 0x00ff0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00ffff00\n", color);
7015 color = getPixelColor(device, 160, 120);
7016 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7017 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7018 color = getPixelColor(device, 480, 160);
7019 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7022 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7023 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7025 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7026 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7028 /* Now find out if the whole streams are re-read, or just the last active value for the
7029 * vertices is used.
7031 hr = IDirect3DDevice9_BeginScene(device);
7032 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7033 if(SUCCEEDED(hr))
7035 float quad1_modified[] = {
7036 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
7037 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
7038 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
7039 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
7041 float quad2_modified[] = {
7042 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
7043 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
7044 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
7045 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
7048 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7051 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7052 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7054 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7056 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7059 if(i == 3 || i == 2) {
7060 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7061 } else if(i == 1) {
7062 /* Succeeds or fails, depending on SW or HW vertex processing */
7063 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
7066 hr = IDirect3DDevice9_EndScene(device);
7067 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7070 color = getPixelColor(device, 480, 350);
7071 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7072 * as well.
7074 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7075 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7076 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7077 * refrast's result.
7079 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7081 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000,
7082 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000ff, 0x00808080 or 0x00000000\n", color);
7084 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7085 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7087 IDirect3DDevice9_SetVertexShader(device, NULL);
7088 IDirect3DDevice9_SetPixelShader(device, NULL);
7089 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7091 IDirect3DVertexShader9_Release(swapped_shader);
7094 for(i = 1; i <= 3; i++) {
7095 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7096 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7097 if(i == 3) {
7098 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
7099 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7100 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
7101 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7102 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7103 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7104 } else if(i == 2){
7105 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7107 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
7108 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7109 } else if(i == 1) {
7110 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
7111 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7112 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
7113 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7116 hr = IDirect3DDevice9_BeginScene(device);
7117 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7118 if(SUCCEEDED(hr))
7120 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
7121 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7122 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
7123 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7125 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7127 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
7128 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7130 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
7131 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7132 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
7133 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7135 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7137 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
7138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7139 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
7140 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7141 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7142 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7144 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
7145 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7147 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7149 hr = IDirect3DDevice9_EndScene(device);
7150 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7152 IDirect3DDevice9_SetVertexShader(device, NULL);
7153 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7154 IDirect3DDevice9_SetPixelShader(device, NULL);
7156 color = getPixelColor(device, 160, 360);
7157 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7158 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7159 color = getPixelColor(device, 480, 360);
7160 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7161 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7162 color = getPixelColor(device, 160, 120);
7163 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7164 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7165 color = getPixelColor(device, 480, 160);
7166 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7167 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7169 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7170 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7172 IDirect3DVertexShader9_Release(texcoord_color_shader);
7173 IDirect3DVertexShader9_Release(color_color_shader);
7176 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
7177 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
7178 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
7179 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
7181 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
7182 IDirect3DVertexDeclaration9_Release(decl_color_color);
7183 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
7184 IDirect3DVertexDeclaration9_Release(decl_color_float);
7186 IDirect3DPixelShader9_Release(ps);
7189 static void srgbtexture_test(IDirect3DDevice9 *device)
7191 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
7192 * texture stage state to render a quad using that texture. The resulting
7193 * color components should be 0x36 (~ 0.21), per this formula:
7194 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
7195 * This is true where srgb_color > 0.04045. */
7196 struct IDirect3DTexture9 *texture = NULL;
7197 struct IDirect3DSurface9 *surface = NULL;
7198 IDirect3D9 *d3d = NULL;
7199 HRESULT hr;
7200 D3DLOCKED_RECT lr;
7201 DWORD color;
7202 float quad[] = {
7203 -1.0, 1.0, 0.0, 0.0, 0.0,
7204 1.0, 1.0, 0.0, 1.0, 0.0,
7205 -1.0, -1.0, 0.0, 0.0, 1.0,
7206 1.0, -1.0, 0.0, 1.0, 1.0,
7210 memset(&lr, 0, sizeof(lr));
7211 IDirect3DDevice9_GetDirect3D(device, &d3d);
7212 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7213 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
7214 D3DFMT_A8R8G8B8) != D3D_OK) {
7215 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
7216 goto out;
7219 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
7220 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
7221 &texture, NULL);
7222 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
7223 if(!texture) {
7224 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
7225 goto out;
7227 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7228 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
7230 fill_surface(surface, 0xff7f7f7f);
7231 IDirect3DSurface9_Release(surface);
7233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7235 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7236 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7238 hr = IDirect3DDevice9_BeginScene(device);
7239 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7240 if(SUCCEEDED(hr))
7242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
7243 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7245 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7246 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
7250 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
7252 hr = IDirect3DDevice9_EndScene(device);
7253 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7256 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7258 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7259 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7261 color = getPixelColor(device, 320, 240);
7262 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7264 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7265 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7267 out:
7268 if(texture) IDirect3DTexture9_Release(texture);
7269 IDirect3D9_Release(d3d);
7272 static void shademode_test(IDirect3DDevice9 *device)
7274 /* Render a quad and try all of the different fixed function shading models. */
7275 struct IDirect3DVertexBuffer9 *vb_strip = NULL;
7276 struct IDirect3DVertexBuffer9 *vb_list = NULL;
7277 HRESULT hr;
7278 DWORD color0, color1;
7279 DWORD color0_gouraud = 0, color1_gouraud = 0;
7280 DWORD shademode = D3DSHADE_FLAT;
7281 DWORD primtype = D3DPT_TRIANGLESTRIP;
7282 LPVOID data = NULL;
7283 UINT i, j;
7284 struct vertex quad_strip[] =
7286 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7287 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7288 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7289 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7291 struct vertex quad_list[] =
7293 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7294 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7295 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7297 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7298 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7299 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7302 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7303 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7304 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7305 if (FAILED(hr)) goto bail;
7307 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7308 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7309 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7310 if (FAILED(hr)) goto bail;
7312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7315 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7316 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7318 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7319 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7320 memcpy(data, quad_strip, sizeof(quad_strip));
7321 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7322 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7324 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7325 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7326 memcpy(data, quad_list, sizeof(quad_list));
7327 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7328 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7330 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
7331 * the color fixups we have to do for FLAT shading will be dependent on that. */
7332 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7333 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7335 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7336 for (j=0; j<2; j++) {
7338 /* Inner loop just changes the D3DRS_SHADEMODE */
7339 for (i=0; i<3; i++) {
7340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7341 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7343 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7344 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7346 hr = IDirect3DDevice9_BeginScene(device);
7347 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7348 if(SUCCEEDED(hr))
7350 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7351 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7353 hr = IDirect3DDevice9_EndScene(device);
7354 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7357 /* Sample two spots from the output */
7358 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7359 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7360 switch(shademode) {
7361 case D3DSHADE_FLAT:
7362 /* Should take the color of the first vertex of each triangle */
7363 if (0)
7365 /* This test depends on EXT_provoking_vertex being
7366 * available. This extension is currently (20090810)
7367 * not common enough to let the test fail if it isn't
7368 * present. */
7369 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7370 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7372 shademode = D3DSHADE_GOURAUD;
7373 break;
7374 case D3DSHADE_GOURAUD:
7375 /* Should be an interpolated blend */
7377 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7378 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7379 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7380 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7382 color0_gouraud = color0;
7383 color1_gouraud = color1;
7385 shademode = D3DSHADE_PHONG;
7386 break;
7387 case D3DSHADE_PHONG:
7388 /* Should be the same as GOURAUD, since no hardware implements this */
7389 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7390 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7391 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7392 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7394 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7395 color0_gouraud, color0);
7396 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7397 color1_gouraud, color1);
7398 break;
7402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7405 /* Now, do it all over again with a TRIANGLELIST */
7406 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7407 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7408 primtype = D3DPT_TRIANGLELIST;
7409 shademode = D3DSHADE_FLAT;
7412 bail:
7413 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7414 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7416 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7418 if (vb_strip)
7419 IDirect3DVertexBuffer9_Release(vb_strip);
7420 if (vb_list)
7421 IDirect3DVertexBuffer9_Release(vb_list);
7424 static void alpha_test(IDirect3DDevice9 *device)
7426 HRESULT hr;
7427 IDirect3DTexture9 *offscreenTexture;
7428 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7429 DWORD color;
7431 struct vertex quad1[] =
7433 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7434 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7435 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7436 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7438 struct vertex quad2[] =
7440 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7441 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7442 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7443 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7445 static const float composite_quad[][5] = {
7446 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7447 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7448 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7449 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7452 /* Clear the render target with alpha = 0.5 */
7453 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7454 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7456 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7457 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7459 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7460 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7461 if(!backbuffer) {
7462 goto out;
7465 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7466 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7467 if(!offscreen) {
7468 goto out;
7471 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7472 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7474 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7475 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7476 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7477 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7478 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7479 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7480 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7481 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7483 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7486 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7487 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7489 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7493 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7495 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7498 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7500 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7501 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7502 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7504 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7505 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7506 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7507 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7508 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7509 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7510 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7515 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7516 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7517 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7520 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7522 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7524 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7526 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7527 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7529 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7530 * Disable alpha blending for the final composition
7532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7533 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7534 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7535 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7537 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7538 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7540 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7541 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7542 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7544 hr = IDirect3DDevice9_EndScene(device);
7545 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7548 color = getPixelColor(device, 160, 360);
7549 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7550 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7552 color = getPixelColor(device, 160, 120);
7553 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7554 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7556 color = getPixelColor(device, 480, 360);
7557 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7558 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7560 color = getPixelColor(device, 480, 120);
7561 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7562 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7564 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7566 out:
7567 /* restore things */
7568 if(backbuffer) {
7569 IDirect3DSurface9_Release(backbuffer);
7571 if(offscreenTexture) {
7572 IDirect3DTexture9_Release(offscreenTexture);
7574 if(offscreen) {
7575 IDirect3DSurface9_Release(offscreen);
7579 struct vertex_shortcolor {
7580 float x, y, z;
7581 unsigned short r, g, b, a;
7583 struct vertex_floatcolor {
7584 float x, y, z;
7585 float r, g, b, a;
7588 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7590 HRESULT hr;
7591 BOOL s_ok, ub_ok, f_ok;
7592 DWORD color, size, i;
7593 void *data;
7594 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7595 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7596 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7597 D3DDECL_END()
7599 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7600 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7601 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7602 D3DDECL_END()
7604 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7605 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7606 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7607 D3DDECL_END()
7609 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7610 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7611 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7612 D3DDECL_END()
7614 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7615 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7616 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7617 D3DDECL_END()
7619 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7620 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7621 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7622 D3DDECL_END()
7624 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7625 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7626 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7627 D3DDECL_END()
7629 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7630 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7631 IDirect3DVertexBuffer9 *vb, *vb2;
7632 struct vertex quad1[] = /* D3DCOLOR */
7634 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7635 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7636 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7637 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7639 struct vertex quad2[] = /* UBYTE4N */
7641 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7642 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7643 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7644 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7646 struct vertex_shortcolor quad3[] = /* short */
7648 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7649 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7650 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7651 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7653 struct vertex_floatcolor quad4[] =
7655 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7656 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7657 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7658 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7660 DWORD colors[] = {
7661 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7662 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7663 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7664 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7665 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7666 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7667 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7668 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7669 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7670 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7671 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7672 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7673 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7674 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7675 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7676 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7678 float quads[] = {
7679 -1.0, -1.0, 0.1,
7680 -1.0, 0.0, 0.1,
7681 0.0, -1.0, 0.1,
7682 0.0, 0.0, 0.1,
7684 0.0, -1.0, 0.1,
7685 0.0, 0.0, 0.1,
7686 1.0, -1.0, 0.1,
7687 1.0, 0.0, 0.1,
7689 0.0, 0.0, 0.1,
7690 0.0, 1.0, 0.1,
7691 1.0, 0.0, 0.1,
7692 1.0, 1.0, 0.1,
7694 -1.0, 0.0, 0.1,
7695 -1.0, 1.0, 0.1,
7696 0.0, 0.0, 0.1,
7697 0.0, 1.0, 0.1
7699 struct tvertex quad_transformed[] = {
7700 { 90, 110, 0.1, 2.0, 0x00ffff00},
7701 { 570, 110, 0.1, 2.0, 0x00ffff00},
7702 { 90, 300, 0.1, 2.0, 0x00ffff00},
7703 { 570, 300, 0.1, 2.0, 0x00ffff00}
7705 D3DCAPS9 caps;
7707 memset(&caps, 0, sizeof(caps));
7708 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7709 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7711 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7712 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7714 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7715 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7716 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7717 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7718 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7719 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7720 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7721 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7722 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7723 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7724 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7725 } else {
7726 trace("D3DDTCAPS_UBYTE4N not supported\n");
7727 dcl_ubyte_2 = NULL;
7728 dcl_ubyte = NULL;
7730 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7731 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7732 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7733 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7735 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7736 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7737 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7738 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7740 hr = IDirect3DDevice9_BeginScene(device);
7741 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7742 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7743 if(SUCCEEDED(hr)) {
7744 if(dcl_color) {
7745 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7746 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7748 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7751 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7752 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7753 * using software vertex processing. Doh!
7755 if(dcl_ubyte) {
7756 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7757 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7759 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7760 ub_ok = SUCCEEDED(hr);
7763 if(dcl_short) {
7764 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7765 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7767 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7768 s_ok = SUCCEEDED(hr);
7771 if(dcl_float) {
7772 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7773 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7775 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7776 f_ok = SUCCEEDED(hr);
7779 hr = IDirect3DDevice9_EndScene(device);
7780 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7783 if(dcl_short) {
7784 color = getPixelColor(device, 480, 360);
7785 ok(color == 0x000000ff || !s_ok,
7786 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7788 if(dcl_ubyte) {
7789 color = getPixelColor(device, 160, 120);
7790 ok(color == 0x0000ffff || !ub_ok,
7791 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7793 if(dcl_color) {
7794 color = getPixelColor(device, 160, 360);
7795 ok(color == 0x00ffff00,
7796 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7798 if(dcl_float) {
7799 color = getPixelColor(device, 480, 120);
7800 ok(color == 0x00ff0000 || !f_ok,
7801 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7803 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7805 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7806 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7807 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7808 * whether the immediate mode code works
7810 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7811 hr = IDirect3DDevice9_BeginScene(device);
7812 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7813 if(SUCCEEDED(hr)) {
7814 if(dcl_color) {
7815 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7816 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7817 memcpy(data, quad1, sizeof(quad1));
7818 hr = IDirect3DVertexBuffer9_Unlock(vb);
7819 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7820 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7821 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7822 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7823 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7824 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7825 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7828 if(dcl_ubyte) {
7829 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7830 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7831 memcpy(data, quad2, sizeof(quad2));
7832 hr = IDirect3DVertexBuffer9_Unlock(vb);
7833 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7834 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7835 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7836 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7837 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7838 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7839 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7840 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7841 ub_ok = SUCCEEDED(hr);
7844 if(dcl_short) {
7845 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7846 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7847 memcpy(data, quad3, sizeof(quad3));
7848 hr = IDirect3DVertexBuffer9_Unlock(vb);
7849 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7850 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7851 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7852 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7853 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7854 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7855 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7856 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7857 s_ok = SUCCEEDED(hr);
7860 if(dcl_float) {
7861 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7862 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7863 memcpy(data, quad4, sizeof(quad4));
7864 hr = IDirect3DVertexBuffer9_Unlock(vb);
7865 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7866 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7867 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7868 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7869 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7870 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7871 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7872 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7873 f_ok = SUCCEEDED(hr);
7876 hr = IDirect3DDevice9_EndScene(device);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7880 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7882 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7883 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7885 if(dcl_short) {
7886 color = getPixelColor(device, 480, 360);
7887 ok(color == 0x000000ff || !s_ok,
7888 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7890 if(dcl_ubyte) {
7891 color = getPixelColor(device, 160, 120);
7892 ok(color == 0x0000ffff || !ub_ok,
7893 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7895 if(dcl_color) {
7896 color = getPixelColor(device, 160, 360);
7897 ok(color == 0x00ffff00,
7898 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7900 if(dcl_float) {
7901 color = getPixelColor(device, 480, 120);
7902 ok(color == 0x00ff0000 || !f_ok,
7903 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7905 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7907 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7910 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7911 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7912 memcpy(data, quad_transformed, sizeof(quad_transformed));
7913 hr = IDirect3DVertexBuffer9_Unlock(vb);
7914 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7916 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7919 hr = IDirect3DDevice9_BeginScene(device);
7920 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7921 if(SUCCEEDED(hr)) {
7922 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7923 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7924 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7925 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7927 hr = IDirect3DDevice9_EndScene(device);
7928 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7931 color = getPixelColor(device, 88, 108);
7932 ok(color == 0x000000ff,
7933 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7934 color = getPixelColor(device, 92, 108);
7935 ok(color == 0x000000ff,
7936 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7937 color = getPixelColor(device, 88, 112);
7938 ok(color == 0x000000ff,
7939 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7940 color = getPixelColor(device, 92, 112);
7941 ok(color == 0x00ffff00,
7942 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7944 color = getPixelColor(device, 568, 108);
7945 ok(color == 0x000000ff,
7946 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7947 color = getPixelColor(device, 572, 108);
7948 ok(color == 0x000000ff,
7949 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7950 color = getPixelColor(device, 568, 112);
7951 ok(color == 0x00ffff00,
7952 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7953 color = getPixelColor(device, 572, 112);
7954 ok(color == 0x000000ff,
7955 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7957 color = getPixelColor(device, 88, 298);
7958 ok(color == 0x000000ff,
7959 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7960 color = getPixelColor(device, 92, 298);
7961 ok(color == 0x00ffff00,
7962 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7963 color = getPixelColor(device, 88, 302);
7964 ok(color == 0x000000ff,
7965 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7966 color = getPixelColor(device, 92, 302);
7967 ok(color == 0x000000ff,
7968 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7970 color = getPixelColor(device, 568, 298);
7971 ok(color == 0x00ffff00,
7972 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7973 color = getPixelColor(device, 572, 298);
7974 ok(color == 0x000000ff,
7975 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7976 color = getPixelColor(device, 568, 302);
7977 ok(color == 0x000000ff,
7978 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7979 color = getPixelColor(device, 572, 302);
7980 ok(color == 0x000000ff,
7981 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7983 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7985 /* This test is pointless without those two declarations: */
7986 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7987 skip("color-ubyte switching test declarations aren't supported\n");
7988 goto out;
7991 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7992 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7993 memcpy(data, quads, sizeof(quads));
7994 hr = IDirect3DVertexBuffer9_Unlock(vb);
7995 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7996 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7997 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7998 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7999 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
8000 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8001 memcpy(data, colors, sizeof(colors));
8002 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8003 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8005 for(i = 0; i < 2; i++) {
8006 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8007 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8009 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
8010 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8011 if(i == 0) {
8012 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
8013 } else {
8014 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
8016 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8018 hr = IDirect3DDevice9_BeginScene(device);
8019 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
8020 ub_ok = FALSE;
8021 if(SUCCEEDED(hr)) {
8022 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8023 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8024 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8025 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8026 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8027 ub_ok = SUCCEEDED(hr);
8029 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
8030 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8031 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8032 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8034 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8035 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8036 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8037 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8038 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8039 ub_ok = (SUCCEEDED(hr) && ub_ok);
8041 hr = IDirect3DDevice9_EndScene(device);
8042 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
8045 if(i == 0) {
8046 color = getPixelColor(device, 480, 360);
8047 ok(color == 0x00ff0000,
8048 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
8049 color = getPixelColor(device, 160, 120);
8050 ok(color == 0x00ffffff,
8051 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8052 color = getPixelColor(device, 160, 360);
8053 ok(color == 0x000000ff || !ub_ok,
8054 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8055 color = getPixelColor(device, 480, 120);
8056 ok(color == 0x000000ff || !ub_ok,
8057 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8058 } else {
8059 color = getPixelColor(device, 480, 360);
8060 ok(color == 0x000000ff,
8061 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
8062 color = getPixelColor(device, 160, 120);
8063 ok(color == 0x00ffffff,
8064 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8065 color = getPixelColor(device, 160, 360);
8066 ok(color == 0x00ff0000 || !ub_ok,
8067 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8068 color = getPixelColor(device, 480, 120);
8069 ok(color == 0x00ff0000 || !ub_ok,
8070 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8072 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8075 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8076 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8077 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8079 IDirect3DVertexBuffer9_Release(vb2);
8081 out:
8082 IDirect3DVertexBuffer9_Release(vb);
8083 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
8084 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
8085 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
8086 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
8087 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
8088 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
8089 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
8092 struct vertex_float16color {
8093 float x, y, z;
8094 DWORD c1, c2;
8097 static void test_vshader_float16(IDirect3DDevice9 *device)
8099 HRESULT hr;
8100 DWORD color;
8101 void *data;
8102 static const D3DVERTEXELEMENT9 decl_elements[] = {
8103 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8104 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8105 D3DDECL_END()
8107 IDirect3DVertexDeclaration9 *vdecl = NULL;
8108 IDirect3DVertexBuffer9 *buffer = NULL;
8109 IDirect3DVertexShader9 *shader;
8110 static const DWORD shader_code[] =
8112 0xfffe0101, /* vs_1_1 */
8113 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8114 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8115 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8116 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8117 0x0000ffff,
8119 struct vertex_float16color quad[] = {
8120 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
8121 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8122 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
8123 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8125 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
8126 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8127 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
8128 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8130 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
8131 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8132 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
8133 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8135 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
8136 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8137 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
8138 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
8142 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8144 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
8145 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
8146 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8147 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8148 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8149 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8151 hr = IDirect3DDevice9_BeginScene(device);
8152 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8153 if(SUCCEEDED(hr)) {
8154 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
8157 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
8159 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
8161 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
8163 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8165 hr = IDirect3DDevice9_EndScene(device);
8166 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8168 color = getPixelColor(device, 480, 360);
8169 ok(color == 0x00ff0000,
8170 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8171 color = getPixelColor(device, 160, 120);
8172 ok(color == 0x00000000,
8173 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8174 color = getPixelColor(device, 160, 360);
8175 ok(color == 0x0000ff00,
8176 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8177 color = getPixelColor(device, 480, 120);
8178 ok(color == 0x000000ff,
8179 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8180 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8182 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
8183 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8185 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
8186 D3DPOOL_MANAGED, &buffer, NULL);
8187 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
8188 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
8189 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
8190 memcpy(data, quad, sizeof(quad));
8191 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8192 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
8193 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
8194 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8196 hr = IDirect3DDevice9_BeginScene(device);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8198 if(SUCCEEDED(hr)) {
8199 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8200 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8201 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8203 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8204 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8205 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
8206 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8208 hr = IDirect3DDevice9_EndScene(device);
8209 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8212 color = getPixelColor(device, 480, 360);
8213 ok(color == 0x00ff0000,
8214 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8215 color = getPixelColor(device, 160, 120);
8216 ok(color == 0x00000000,
8217 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8218 color = getPixelColor(device, 160, 360);
8219 ok(color == 0x0000ff00,
8220 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8221 color = getPixelColor(device, 480, 120);
8222 ok(color == 0x000000ff,
8223 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8224 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8226 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8227 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8228 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8230 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8231 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8233 IDirect3DVertexDeclaration9_Release(vdecl);
8234 IDirect3DVertexShader9_Release(shader);
8235 IDirect3DVertexBuffer9_Release(buffer);
8238 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
8240 D3DCAPS9 caps;
8241 IDirect3DTexture9 *texture;
8242 HRESULT hr;
8243 D3DLOCKED_RECT rect;
8244 unsigned int x, y;
8245 DWORD *dst, color;
8246 const float quad[] = {
8247 -1.0, -1.0, 0.1, -0.2, -0.2,
8248 1.0, -1.0, 0.1, 1.2, -0.2,
8249 -1.0, 1.0, 0.1, -0.2, 1.2,
8250 1.0, 1.0, 0.1, 1.2, 1.2
8252 memset(&caps, 0, sizeof(caps));
8254 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8255 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8256 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8258 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
8259 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
8260 "Card has conditional NP2 support without power of two restriction set\n");
8262 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8264 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8265 return;
8267 else
8269 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8270 return;
8273 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8276 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8277 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8279 memset(&rect, 0, sizeof(rect));
8280 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8281 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8282 for(y = 0; y < 10; y++) {
8283 for(x = 0; x < 10; x++) {
8284 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8285 if(x == 0 || x == 9 || y == 0 || y == 9) {
8286 *dst = 0x00ff0000;
8287 } else {
8288 *dst = 0x000000ff;
8292 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8293 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8295 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8296 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8297 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8298 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8299 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8300 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8301 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8304 hr = IDirect3DDevice9_BeginScene(device);
8305 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8306 if(SUCCEEDED(hr)) {
8307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8308 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8310 hr = IDirect3DDevice9_EndScene(device);
8311 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8314 color = getPixelColor(device, 1, 1);
8315 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8316 color = getPixelColor(device, 639, 479);
8317 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8319 color = getPixelColor(device, 135, 101);
8320 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8321 color = getPixelColor(device, 140, 101);
8322 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8323 color = getPixelColor(device, 135, 105);
8324 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8325 color = getPixelColor(device, 140, 105);
8326 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8328 color = getPixelColor(device, 135, 376);
8329 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8330 color = getPixelColor(device, 140, 376);
8331 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8332 color = getPixelColor(device, 135, 379);
8333 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8334 color = getPixelColor(device, 140, 379);
8335 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8337 color = getPixelColor(device, 500, 101);
8338 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8339 color = getPixelColor(device, 504, 101);
8340 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8341 color = getPixelColor(device, 500, 105);
8342 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8343 color = getPixelColor(device, 504, 105);
8344 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8346 color = getPixelColor(device, 500, 376);
8347 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8348 color = getPixelColor(device, 504, 376);
8349 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8350 color = getPixelColor(device, 500, 380);
8351 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8352 color = getPixelColor(device, 504, 380);
8353 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8355 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8357 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8358 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8359 IDirect3DTexture9_Release(texture);
8362 static void vFace_register_test(IDirect3DDevice9 *device)
8364 HRESULT hr;
8365 DWORD color;
8366 static const DWORD shader_code[] =
8368 0xffff0300, /* ps_3_0 */
8369 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8370 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8371 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8372 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8373 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8374 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8375 0x0000ffff /* END */
8377 static const DWORD vshader_code[] =
8379 0xfffe0300, /* vs_3_0 */
8380 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8381 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8382 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8383 0x0000ffff /* end */
8385 IDirect3DPixelShader9 *shader;
8386 IDirect3DVertexShader9 *vshader;
8387 IDirect3DTexture9 *texture;
8388 IDirect3DSurface9 *surface, *backbuffer;
8389 const float quad[] = {
8390 -1.0, -1.0, 0.1,
8391 1.0, -1.0, 0.1,
8392 -1.0, 0.0, 0.1,
8394 1.0, -1.0, 0.1,
8395 1.0, 0.0, 0.1,
8396 -1.0, 0.0, 0.1,
8398 -1.0, 0.0, 0.1,
8399 -1.0, 1.0, 0.1,
8400 1.0, 0.0, 0.1,
8402 1.0, 0.0, 0.1,
8403 -1.0, 1.0, 0.1,
8404 1.0, 1.0, 0.1,
8406 const float blit[] = {
8407 0.0, -1.0, 0.1, 0.0, 0.0,
8408 1.0, -1.0, 0.1, 1.0, 0.0,
8409 0.0, 1.0, 0.1, 0.0, 1.0,
8410 1.0, 1.0, 0.1, 1.0, 1.0,
8413 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8414 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8415 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8416 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8417 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8418 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8419 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8420 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8421 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8422 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8423 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8424 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8425 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8426 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8427 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8428 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8431 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8433 hr = IDirect3DDevice9_BeginScene(device);
8434 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8435 if(SUCCEEDED(hr)) {
8436 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8437 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8438 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8439 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8440 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8442 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8443 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8444 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8446 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8448 /* Blit the texture onto the back buffer to make it visible */
8449 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8450 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8451 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8452 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8453 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8455 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8456 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8457 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8458 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8459 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8463 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8465 hr = IDirect3DDevice9_EndScene(device);
8466 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8469 color = getPixelColor(device, 160, 360);
8470 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8471 color = getPixelColor(device, 160, 120);
8472 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8473 color = getPixelColor(device, 480, 360);
8474 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8475 color = getPixelColor(device, 480, 120);
8476 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8477 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8478 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8480 IDirect3DDevice9_SetTexture(device, 0, NULL);
8481 IDirect3DPixelShader9_Release(shader);
8482 IDirect3DVertexShader9_Release(vshader);
8483 IDirect3DSurface9_Release(surface);
8484 IDirect3DSurface9_Release(backbuffer);
8485 IDirect3DTexture9_Release(texture);
8488 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8490 HRESULT hr;
8491 DWORD color;
8492 int i;
8493 D3DCAPS9 caps;
8494 BOOL L6V5U5_supported = FALSE;
8495 IDirect3DTexture9 *tex1, *tex2;
8496 D3DLOCKED_RECT locked_rect;
8498 static const float quad[][7] = {
8499 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8500 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8501 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8502 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8505 static const D3DVERTEXELEMENT9 decl_elements[] = {
8506 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8507 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8508 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8509 D3DDECL_END()
8512 /* use asymmetric matrix to test loading */
8513 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8514 float scale, offset;
8516 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8517 IDirect3DTexture9 *texture = NULL;
8519 memset(&caps, 0, sizeof(caps));
8520 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8521 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8522 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8523 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8524 return;
8525 } else {
8526 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8527 * They report that it is not supported, but after that bump mapping works properly. So just test
8528 * if the format is generally supported, and check the BUMPENVMAP flag
8530 IDirect3D9 *d3d9;
8532 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8533 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8534 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8535 L6V5U5_supported = SUCCEEDED(hr);
8536 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8537 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8538 IDirect3D9_Release(d3d9);
8539 if(FAILED(hr)) {
8540 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8541 return;
8545 /* Generate the textures */
8546 generate_bumpmap_textures(device);
8548 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8549 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8550 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8551 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8552 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8553 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8554 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8555 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8557 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8558 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8559 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8560 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8561 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8562 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8564 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8565 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8566 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8567 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8568 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8569 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8571 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8572 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8574 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8575 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8577 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8578 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8581 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8582 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8583 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8584 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8586 hr = IDirect3DDevice9_BeginScene(device);
8587 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8590 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8592 hr = IDirect3DDevice9_EndScene(device);
8593 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8595 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8596 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8597 * But since testing the color match is not the purpose of the test don't be too picky
8599 color = getPixelColor(device, 320-32, 240);
8600 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8601 color = getPixelColor(device, 320+32, 240);
8602 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8603 color = getPixelColor(device, 320, 240-32);
8604 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8605 color = getPixelColor(device, 320, 240+32);
8606 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8607 color = getPixelColor(device, 320, 240);
8608 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8609 color = getPixelColor(device, 320+32, 240+32);
8610 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8611 color = getPixelColor(device, 320-32, 240+32);
8612 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8613 color = getPixelColor(device, 320+32, 240-32);
8614 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8615 color = getPixelColor(device, 320-32, 240-32);
8616 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8618 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8620 for(i = 0; i < 2; i++) {
8621 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8622 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8623 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8624 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8625 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8626 IDirect3DTexture9_Release(texture); /* To destroy it */
8629 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8630 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8631 goto cleanup;
8633 if(L6V5U5_supported == FALSE) {
8634 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8635 goto cleanup;
8638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8639 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8640 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8641 * would only make this test more complicated
8643 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8644 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8645 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8646 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8648 memset(&locked_rect, 0, sizeof(locked_rect));
8649 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8650 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8651 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8652 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8653 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8655 memset(&locked_rect, 0, sizeof(locked_rect));
8656 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8657 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8658 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8659 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8660 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8662 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8663 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8664 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8665 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8667 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8668 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8669 scale = 2.0;
8670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8671 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8672 offset = 0.1;
8673 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8674 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8676 hr = IDirect3DDevice9_BeginScene(device);
8677 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8678 if(SUCCEEDED(hr)) {
8679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8680 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8681 hr = IDirect3DDevice9_EndScene(device);
8682 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8685 color = getPixelColor(device, 320, 240);
8686 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8687 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8688 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8690 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8691 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8692 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8694 /* Check a result scale factor > 1.0 */
8695 scale = 10;
8696 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8697 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8698 offset = 10;
8699 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8700 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8702 hr = IDirect3DDevice9_BeginScene(device);
8703 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8704 if(SUCCEEDED(hr)) {
8705 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8706 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8707 hr = IDirect3DDevice9_EndScene(device);
8708 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8710 color = getPixelColor(device, 320, 240);
8711 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8712 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8713 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8715 /* Check clamping in the scale factor calculation */
8716 scale = 1000;
8717 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8718 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8719 offset = -1;
8720 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8721 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8723 hr = IDirect3DDevice9_BeginScene(device);
8724 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8725 if(SUCCEEDED(hr)) {
8726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8727 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8728 hr = IDirect3DDevice9_EndScene(device);
8729 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8731 color = getPixelColor(device, 320, 240);
8732 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8733 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8734 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8736 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8737 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8738 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8739 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8741 IDirect3DTexture9_Release(tex1);
8742 IDirect3DTexture9_Release(tex2);
8744 cleanup:
8745 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8746 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8747 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8748 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8750 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8751 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8752 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8755 static void stencil_cull_test(IDirect3DDevice9 *device) {
8756 HRESULT hr;
8757 IDirect3DSurface9 *depthstencil = NULL;
8758 D3DSURFACE_DESC desc;
8759 float quad1[] = {
8760 -1.0, -1.0, 0.1,
8761 0.0, -1.0, 0.1,
8762 -1.0, 0.0, 0.1,
8763 0.0, 0.0, 0.1,
8765 float quad2[] = {
8766 0.0, -1.0, 0.1,
8767 1.0, -1.0, 0.1,
8768 0.0, 0.0, 0.1,
8769 1.0, 0.0, 0.1,
8771 float quad3[] = {
8772 0.0, 0.0, 0.1,
8773 1.0, 0.0, 0.1,
8774 0.0, 1.0, 0.1,
8775 1.0, 1.0, 0.1,
8777 float quad4[] = {
8778 -1.0, 0.0, 0.1,
8779 0.0, 0.0, 0.1,
8780 -1.0, 1.0, 0.1,
8781 0.0, 1.0, 0.1,
8783 struct vertex painter[] = {
8784 {-1.0, -1.0, 0.0, 0x00000000},
8785 { 1.0, -1.0, 0.0, 0x00000000},
8786 {-1.0, 1.0, 0.0, 0x00000000},
8787 { 1.0, 1.0, 0.0, 0x00000000},
8789 WORD indices_cw[] = {0, 1, 3};
8790 WORD indices_ccw[] = {0, 2, 3};
8791 unsigned int i;
8792 DWORD color;
8794 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8795 if(depthstencil == NULL) {
8796 skip("No depth stencil buffer\n");
8797 return;
8799 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8800 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8801 IDirect3DSurface9_Release(depthstencil);
8802 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8803 skip("No 4 or 8 bit stencil surface\n");
8804 return;
8807 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8808 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8809 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8810 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8813 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8817 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8819 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8826 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8829 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8831 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8833 /* First pass: Fill the stencil buffer with some values... */
8834 hr = IDirect3DDevice9_BeginScene(device);
8835 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8836 if(SUCCEEDED(hr))
8838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8840 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8841 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8842 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8843 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8844 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8845 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8851 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8852 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8853 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8854 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8855 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8856 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8859 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8860 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8861 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8862 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8863 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8864 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8865 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8868 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8869 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8870 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8871 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8872 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8873 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8874 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8876 hr = IDirect3DDevice9_EndScene(device);
8877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8881 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8882 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8883 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8884 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8885 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8893 /* 2nd pass: Make the stencil values visible */
8894 hr = IDirect3DDevice9_BeginScene(device);
8895 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8896 if(SUCCEEDED(hr))
8898 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8899 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8900 for (i = 0; i < 16; ++i)
8902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8905 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8906 painter[1].diffuse = (i * 16);
8907 painter[2].diffuse = (i * 16);
8908 painter[3].diffuse = (i * 16);
8909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8910 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8912 hr = IDirect3DDevice9_EndScene(device);
8913 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8919 color = getPixelColor(device, 160, 420);
8920 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8921 color = getPixelColor(device, 160, 300);
8922 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8924 color = getPixelColor(device, 480, 420);
8925 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8926 color = getPixelColor(device, 480, 300);
8927 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8929 color = getPixelColor(device, 160, 180);
8930 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8931 color = getPixelColor(device, 160, 60);
8932 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8934 color = getPixelColor(device, 480, 180);
8935 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8936 color = getPixelColor(device, 480, 60);
8937 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8939 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8940 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8943 static void vpos_register_test(IDirect3DDevice9 *device)
8945 HRESULT hr;
8946 DWORD color;
8947 static const DWORD shader_code[] =
8949 0xffff0300, /* ps_3_0 */
8950 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8951 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8952 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8953 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8954 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8955 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8956 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8957 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8958 0x0000ffff /* end */
8960 static const DWORD shader_frac_code[] =
8962 0xffff0300, /* ps_3_0 */
8963 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8964 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8965 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8966 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8967 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8968 0x0000ffff /* end */
8970 static const DWORD vshader_code[] =
8972 0xfffe0300, /* vs_3_0 */
8973 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8974 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8975 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8976 0x0000ffff /* end */
8978 IDirect3DVertexShader9 *vshader;
8979 IDirect3DPixelShader9 *shader, *shader_frac;
8980 IDirect3DSurface9 *surface = NULL, *backbuffer;
8981 const float quad[] = {
8982 -1.0, -1.0, 0.1, 0.0, 0.0,
8983 1.0, -1.0, 0.1, 1.0, 0.0,
8984 -1.0, 1.0, 0.1, 0.0, 1.0,
8985 1.0, 1.0, 0.1, 1.0, 1.0,
8987 D3DLOCKED_RECT lr;
8988 float constant[4] = {1.0, 0.0, 320, 240};
8989 DWORD *pos;
8991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8992 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8993 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8994 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8995 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8996 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8997 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8998 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8999 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9000 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9001 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9002 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9004 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9005 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9006 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9008 hr = IDirect3DDevice9_BeginScene(device);
9009 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9010 if(SUCCEEDED(hr)) {
9011 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9012 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
9013 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9014 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9015 hr = IDirect3DDevice9_EndScene(device);
9016 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9019 /* This has to be pixel exact */
9020 color = getPixelColor(device, 319, 239);
9021 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
9022 color = getPixelColor(device, 320, 239);
9023 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
9024 color = getPixelColor(device, 319, 240);
9025 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
9026 color = getPixelColor(device, 320, 240);
9027 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
9028 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9030 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
9031 &surface, NULL);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
9033 hr = IDirect3DDevice9_BeginScene(device);
9034 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9035 if(SUCCEEDED(hr)) {
9036 constant[2] = 16; constant[3] = 16;
9037 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9038 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
9039 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9042 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9043 hr = IDirect3DDevice9_EndScene(device);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9046 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9047 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9049 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9050 color = *pos & 0x00ffffff;
9051 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
9052 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
9053 color = *pos & 0x00ffffff;
9054 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
9055 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
9056 color = *pos & 0x00ffffff;
9057 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
9058 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
9059 color = *pos & 0x00ffffff;
9060 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
9062 hr = IDirect3DSurface9_UnlockRect(surface);
9063 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9065 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
9066 * have full control over the multisampling setting inside this test
9068 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
9069 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9070 hr = IDirect3DDevice9_BeginScene(device);
9071 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9072 if(SUCCEEDED(hr)) {
9073 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9074 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9076 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9077 hr = IDirect3DDevice9_EndScene(device);
9078 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9080 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9081 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9083 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9084 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9086 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9087 color = *pos & 0x00ffffff;
9088 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
9090 hr = IDirect3DSurface9_UnlockRect(surface);
9091 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9093 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9094 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9095 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9096 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9097 IDirect3DPixelShader9_Release(shader);
9098 IDirect3DPixelShader9_Release(shader_frac);
9099 IDirect3DVertexShader9_Release(vshader);
9100 if(surface) IDirect3DSurface9_Release(surface);
9101 IDirect3DSurface9_Release(backbuffer);
9104 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
9106 D3DCOLOR color;
9108 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
9109 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9110 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9111 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9112 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9114 ++r;
9115 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
9116 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9117 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9118 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9119 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9121 return TRUE;
9124 static void pointsize_test(IDirect3DDevice9 *device)
9126 HRESULT hr;
9127 D3DCAPS9 caps;
9128 D3DMATRIX matrix;
9129 D3DMATRIX identity;
9130 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
9131 DWORD color;
9132 IDirect3DSurface9 *rt, *backbuffer;
9133 IDirect3DTexture9 *tex1, *tex2;
9134 RECT rect = {0, 0, 128, 128};
9135 D3DLOCKED_RECT lr;
9136 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
9137 0x00000000, 0x00000000};
9138 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
9139 0x00000000, 0x0000ff00};
9141 const float vertices[] = {
9142 64, 64, 0.1,
9143 128, 64, 0.1,
9144 192, 64, 0.1,
9145 256, 64, 0.1,
9146 320, 64, 0.1,
9147 384, 64, 0.1,
9148 448, 64, 0.1,
9149 512, 64, 0.1,
9152 /* 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 */
9153 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;
9154 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;
9155 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;
9156 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;
9158 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;
9159 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;
9160 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;
9161 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;
9163 memset(&caps, 0, sizeof(caps));
9164 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9165 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9166 if(caps.MaxPointSize < 32.0) {
9167 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
9168 return;
9171 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9172 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9173 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9174 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9175 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9176 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9177 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
9178 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
9180 hr = IDirect3DDevice9_BeginScene(device);
9181 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9182 if (SUCCEEDED(hr))
9184 ptsize = 15.0;
9185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9186 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9188 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9190 ptsize = 31.0;
9191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9192 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
9194 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9196 ptsize = 30.75;
9197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9198 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
9200 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9202 if (caps.MaxPointSize >= 63.0)
9204 ptsize = 63.0;
9205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
9208 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9210 ptsize = 62.75;
9211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9212 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
9214 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9217 ptsize = 1.0;
9218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9219 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
9221 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9223 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
9224 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9225 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
9226 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9228 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
9229 ptsize = 15.0;
9230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9231 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9232 ptsize = 1.0;
9233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
9234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
9236 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
9239 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9241 /* pointsize < pointsize_min < pointsize_max?
9242 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
9243 ptsize = 1.0;
9244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9245 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9246 ptsize = 15.0;
9247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
9248 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9249 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
9250 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9252 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
9253 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9255 hr = IDirect3DDevice9_EndScene(device);
9256 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9259 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
9260 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
9261 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
9263 if (caps.MaxPointSize >= 63.0)
9265 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9266 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9269 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9270 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9271 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9272 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9273 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9275 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9277 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9278 * generates texture coordinates for the point(result: Yes, it does)
9280 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9281 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9282 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9285 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9287 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9288 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9289 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9290 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9291 memset(&lr, 0, sizeof(lr));
9292 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9293 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9294 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9295 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9296 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9297 memset(&lr, 0, sizeof(lr));
9298 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9299 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9300 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9301 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9302 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9303 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9304 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9305 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9306 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9307 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9308 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9309 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9311 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9312 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9313 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9314 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9315 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9316 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9320 ptsize = 32.0;
9321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9322 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9324 hr = IDirect3DDevice9_BeginScene(device);
9325 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9326 if(SUCCEEDED(hr))
9328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9329 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9330 hr = IDirect3DDevice9_EndScene(device);
9331 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9334 color = getPixelColor(device, 64-4, 64-4);
9335 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9336 color = getPixelColor(device, 64-4, 64+4);
9337 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9338 color = getPixelColor(device, 64+4, 64+4);
9339 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9340 color = getPixelColor(device, 64+4, 64-4);
9341 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9342 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9344 U(matrix).m[0][0] = 1.0f / 64.0f;
9345 U(matrix).m[1][1] = -1.0f / 64.0f;
9346 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9347 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9349 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9350 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9352 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9353 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9354 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9356 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9357 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9359 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9361 hr = IDirect3DDevice9_BeginScene(device);
9362 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9363 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9364 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9365 hr = IDirect3DDevice9_EndScene(device);
9366 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9368 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9369 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9370 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9371 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9372 IDirect3DSurface9_Release(backbuffer);
9373 IDirect3DSurface9_Release(rt);
9375 color = getPixelColor(device, 64-4, 64-4);
9376 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9377 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9378 color = getPixelColor(device, 64+4, 64-4);
9379 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9380 "Expected color 0x00ffff00, got 0x%08x.\n", color);
9381 color = getPixelColor(device, 64-4, 64+4);
9382 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9383 "Expected color 0x00000000, got 0x%08x.\n", color);
9384 color = getPixelColor(device, 64+4, 64+4);
9385 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9386 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9389 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9391 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9392 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9393 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9394 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9395 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9396 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9397 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9398 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9399 IDirect3DTexture9_Release(tex1);
9400 IDirect3DTexture9_Release(tex2);
9402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9403 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9404 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9405 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9406 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9407 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9410 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9412 static const DWORD vshader_code[] =
9414 0xfffe0300, /* vs_3_0 */
9415 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9416 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9417 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9418 0x0000ffff /* end */
9420 static const DWORD pshader_code1[] =
9422 0xffff0300, /* ps_3_0 */
9423 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9424 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9425 0x0000ffff /* end */
9427 static const DWORD pshader_code2[] =
9429 0xffff0300, /* ps_3_0 */
9430 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9431 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9432 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9433 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9434 0x0000ffff /* end */
9437 HRESULT hr;
9438 IDirect3DVertexShader9 *vs;
9439 IDirect3DPixelShader9 *ps1, *ps2;
9440 IDirect3DTexture9 *tex1, *tex2;
9441 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9442 D3DCAPS9 caps;
9443 DWORD color;
9444 UINT i, j;
9445 float quad[] = {
9446 -1.0, -1.0, 0.1,
9447 1.0, -1.0, 0.1,
9448 -1.0, 1.0, 0.1,
9449 1.0, 1.0, 0.1,
9451 float texquad[] = {
9452 -1.0, -1.0, 0.1, 0.0, 0.0,
9453 0.0, -1.0, 0.1, 1.0, 0.0,
9454 -1.0, 1.0, 0.1, 0.0, 1.0,
9455 0.0, 1.0, 0.1, 1.0, 1.0,
9457 0.0, -1.0, 0.1, 0.0, 0.0,
9458 1.0, -1.0, 0.1, 1.0, 0.0,
9459 0.0, 1.0, 0.1, 0.0, 1.0,
9460 1.0, 1.0, 0.1, 1.0, 1.0,
9463 memset(&caps, 0, sizeof(caps));
9464 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9465 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9466 if(caps.NumSimultaneousRTs < 2) {
9467 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9468 return;
9471 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9472 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9474 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9475 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9476 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9478 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9479 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9480 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9481 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9482 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9483 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9484 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9485 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9486 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9487 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9488 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9489 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9491 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9492 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9493 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9494 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9495 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9496 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9498 hr = IDirect3DDevice9_SetVertexShader(device, vs);
9499 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9501 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9502 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9504 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9505 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9507 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9508 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9509 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9510 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9511 color = getPixelColorFromSurface(readback, 8, 8);
9512 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9513 "Expected color 0x000000ff, got 0x%08x.\n", color);
9514 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9515 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9516 color = getPixelColorFromSurface(readback, 8, 8);
9517 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9518 "Expected color 0x000000ff, got 0x%08x.\n", color);
9520 /* Render targets not written by the pixel shader should be unmodified. */
9521 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9522 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9523 hr = IDirect3DDevice9_BeginScene(device);
9524 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9526 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9527 hr = IDirect3DDevice9_EndScene(device);
9528 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9529 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9530 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9531 color = getPixelColorFromSurface(readback, 8, 8);
9532 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9533 "Expected color 0xff00ff00, got 0x%08x.\n", color);
9534 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9535 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9536 for (i = 6; i < 10; ++i)
9538 for (j = 6; j < 10; ++j)
9540 color = getPixelColorFromSurface(readback, j, i);
9541 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9542 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9546 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9547 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9548 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9549 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9550 color = getPixelColorFromSurface(readback, 8, 8);
9551 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9552 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9553 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9554 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9555 color = getPixelColorFromSurface(readback, 8, 8);
9556 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9557 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9559 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9560 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9562 hr = IDirect3DDevice9_BeginScene(device);
9563 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9564 if(SUCCEEDED(hr)) {
9565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9566 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9568 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9569 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9570 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9571 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9572 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9573 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9574 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9576 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9577 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9579 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9580 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9582 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9584 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9585 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9587 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9589 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9590 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9592 hr = IDirect3DDevice9_EndScene(device);
9593 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9596 color = getPixelColor(device, 160, 240);
9597 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9598 color = getPixelColor(device, 480, 240);
9599 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9600 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9602 IDirect3DPixelShader9_Release(ps2);
9603 IDirect3DPixelShader9_Release(ps1);
9604 IDirect3DVertexShader9_Release(vs);
9605 IDirect3DTexture9_Release(tex1);
9606 IDirect3DTexture9_Release(tex2);
9607 IDirect3DSurface9_Release(surf1);
9608 IDirect3DSurface9_Release(surf2);
9609 IDirect3DSurface9_Release(backbuf);
9610 IDirect3DSurface9_Release(readback);
9613 struct formats {
9614 const char *fmtName;
9615 D3DFORMAT textureFormat;
9616 DWORD resultColorBlending;
9617 DWORD resultColorNoBlending;
9620 static const struct formats test_formats[] = {
9621 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9622 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9623 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9624 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9625 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9626 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9627 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9628 { NULL, 0 }
9631 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9633 HRESULT hr;
9634 IDirect3DTexture9 *offscreenTexture = NULL;
9635 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9636 IDirect3D9 *d3d = NULL;
9637 DWORD color;
9638 DWORD r0, g0, b0, r1, g1, b1;
9639 int fmt_index;
9641 static const float quad[][5] = {
9642 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9643 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9644 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9645 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9648 /* Quad with R=0x10, G=0x20 */
9649 static const struct vertex quad1[] = {
9650 {-1.0f, -1.0f, 0.1f, 0x80102000},
9651 {-1.0f, 1.0f, 0.1f, 0x80102000},
9652 { 1.0f, -1.0f, 0.1f, 0x80102000},
9653 { 1.0f, 1.0f, 0.1f, 0x80102000},
9656 /* Quad with R=0x20, G=0x10 */
9657 static const struct vertex quad2[] = {
9658 {-1.0f, -1.0f, 0.1f, 0x80201000},
9659 {-1.0f, 1.0f, 0.1f, 0x80201000},
9660 { 1.0f, -1.0f, 0.1f, 0x80201000},
9661 { 1.0f, 1.0f, 0.1f, 0x80201000},
9664 IDirect3DDevice9_GetDirect3D(device, &d3d);
9666 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9667 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9668 if(!backbuffer) {
9669 goto out;
9672 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9674 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9676 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9677 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9679 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9680 continue;
9683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9684 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9686 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9687 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9688 if(!offscreenTexture) {
9689 continue;
9692 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9693 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9694 if(!offscreen) {
9695 continue;
9698 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9699 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9701 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9702 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9703 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9704 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9705 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9706 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9707 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9708 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9710 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9712 /* Below we will draw two quads with different colors and try to blend them together.
9713 * The result color is compared with the expected outcome.
9715 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9716 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9717 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9718 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9719 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9722 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9724 /* Draw a quad using color 0x0010200 */
9725 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9726 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9728 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9730 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9732 /* Draw a quad using color 0x0020100 */
9733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9734 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9736 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9738 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9740 /* We don't want to blend the result on the backbuffer */
9741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9742 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9744 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9745 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9746 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9747 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9748 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9750 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9751 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9753 /* This time with the texture */
9754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9755 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9757 IDirect3DDevice9_EndScene(device);
9760 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9761 /* Compare the color of the center quad with our expectation */
9762 color = getPixelColor(device, 320, 240);
9763 r0 = (color & 0x00ff0000) >> 16;
9764 g0 = (color & 0x0000ff00) >> 8;
9765 b0 = (color & 0x000000ff) >> 0;
9767 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9768 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9769 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9771 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9772 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9773 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9774 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9775 } else {
9776 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9777 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9778 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9779 color = getPixelColor(device, 320, 240);
9780 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);
9782 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9784 IDirect3DDevice9_SetTexture(device, 0, NULL);
9785 if(offscreenTexture) {
9786 IDirect3DTexture9_Release(offscreenTexture);
9788 if(offscreen) {
9789 IDirect3DSurface9_Release(offscreen);
9793 out:
9794 /* restore things */
9795 if(backbuffer) {
9796 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9797 IDirect3DSurface9_Release(backbuffer);
9801 static void tssargtemp_test(IDirect3DDevice9 *device)
9803 HRESULT hr;
9804 DWORD color;
9805 static const struct vertex quad[] = {
9806 {-1.0, -1.0, 0.1, 0x00ff0000},
9807 { 1.0, -1.0, 0.1, 0x00ff0000},
9808 {-1.0, 1.0, 0.1, 0x00ff0000},
9809 { 1.0, 1.0, 0.1, 0x00ff0000}
9811 D3DCAPS9 caps;
9813 memset(&caps, 0, sizeof(caps));
9814 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9815 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9816 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9817 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9818 return;
9821 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9822 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9824 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9825 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9826 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9827 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9829 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9830 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9831 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9832 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9833 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9834 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9836 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9837 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9838 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9839 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9840 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9841 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9843 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9844 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9847 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9848 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9849 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9851 hr = IDirect3DDevice9_BeginScene(device);
9852 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9853 if(SUCCEEDED(hr)) {
9854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9855 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9856 hr = IDirect3DDevice9_EndScene(device);
9857 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9859 color = getPixelColor(device, 320, 240);
9860 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
9861 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9863 /* Set stage 1 back to default */
9864 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9865 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9866 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9867 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9868 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9869 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9870 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9871 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9872 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9873 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9876 struct testdata
9878 DWORD idxVertex; /* number of instances in the first stream */
9879 DWORD idxColor; /* number of instances in the second stream */
9880 DWORD idxInstance; /* should be 1 ?? */
9881 DWORD color1; /* color 1 instance */
9882 DWORD color2; /* color 2 instance */
9883 DWORD color3; /* color 3 instance */
9884 DWORD color4; /* color 4 instance */
9885 WORD strVertex; /* specify which stream to use 0-2*/
9886 WORD strColor;
9887 WORD strInstance;
9890 static const struct testdata testcases[]=
9892 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9893 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9894 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9895 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9896 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9897 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9898 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9899 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9900 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9901 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9902 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9903 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9904 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9905 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9907 This draws one instance on some machines, no instance on others
9908 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9911 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9912 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9916 /* Drawing Indexed Geometry with instances*/
9917 static void stream_test(IDirect3DDevice9 *device)
9919 IDirect3DVertexBuffer9 *vb = NULL;
9920 IDirect3DVertexBuffer9 *vb2 = NULL;
9921 IDirect3DVertexBuffer9 *vb3 = NULL;
9922 IDirect3DIndexBuffer9 *ib = NULL;
9923 IDirect3DVertexDeclaration9 *pDecl = NULL;
9924 IDirect3DVertexShader9 *shader = NULL;
9925 HRESULT hr;
9926 BYTE *data;
9927 DWORD color;
9928 DWORD ind;
9929 unsigned i;
9931 static const DWORD shader_code[] =
9933 0xfffe0101, /* vs_1_1 */
9934 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9935 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9936 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9937 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9938 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9939 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9940 0x0000ffff
9943 const float quad[][3] =
9945 {-0.5f, -0.5f, 1.1f}, /*0 */
9946 {-0.5f, 0.5f, 1.1f}, /*1 */
9947 { 0.5f, -0.5f, 1.1f}, /*2 */
9948 { 0.5f, 0.5f, 1.1f}, /*3 */
9951 const float vertcolor[][4] =
9953 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9954 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9955 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9956 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9959 /* 4 position for 4 instances */
9960 const float instancepos[][3] =
9962 {-0.6f,-0.6f, 0.0f},
9963 { 0.6f,-0.6f, 0.0f},
9964 { 0.6f, 0.6f, 0.0f},
9965 {-0.6f, 0.6f, 0.0f},
9968 short indices[] = {0, 1, 2, 1, 2, 3};
9970 D3DVERTEXELEMENT9 decl[] =
9972 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9973 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9974 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9975 D3DDECL_END()
9978 /* set the default value because it isn't done in wine? */
9979 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9980 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9982 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9983 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9984 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9986 /* check wrong cases */
9987 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9988 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9989 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9990 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9991 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9992 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9993 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9994 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9995 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9996 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9997 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9998 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9999 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
10000 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10001 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10002 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10003 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
10004 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10005 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10006 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10008 /* set the default value back */
10009 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10010 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10012 /* create all VertexBuffers*/
10013 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
10014 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10015 if(!vb) {
10016 skip("Failed to create a vertex buffer\n");
10017 return;
10019 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
10020 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10021 if(!vb2) {
10022 skip("Failed to create a vertex buffer\n");
10023 goto out;
10025 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
10026 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10027 if(!vb3) {
10028 skip("Failed to create a vertex buffer\n");
10029 goto out;
10032 /* create IndexBuffer*/
10033 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
10034 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
10035 if(!ib) {
10036 skip("Failed to create a index buffer\n");
10037 goto out;
10040 /* copy all Buffers (Vertex + Index)*/
10041 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
10042 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10043 memcpy(data, quad, sizeof(quad));
10044 hr = IDirect3DVertexBuffer9_Unlock(vb);
10045 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10046 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
10047 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10048 memcpy(data, vertcolor, sizeof(vertcolor));
10049 hr = IDirect3DVertexBuffer9_Unlock(vb2);
10050 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10051 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
10052 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10053 memcpy(data, instancepos, sizeof(instancepos));
10054 hr = IDirect3DVertexBuffer9_Unlock(vb3);
10055 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10056 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
10057 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
10058 memcpy(data, indices, sizeof(indices));
10059 hr = IDirect3DIndexBuffer9_Unlock(ib);
10060 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
10062 /* create VertexShader */
10063 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10064 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10065 if(!shader) {
10066 skip("Failed to create a vetex shader\n");
10067 goto out;
10070 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10071 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10073 hr = IDirect3DDevice9_SetIndices(device, ib);
10074 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
10076 /* run all tests */
10077 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
10079 struct testdata act = testcases[i];
10080 decl[0].Stream = act.strVertex;
10081 decl[1].Stream = act.strColor;
10082 decl[2].Stream = act.strInstance;
10083 /* create VertexDeclarations */
10084 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
10085 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
10087 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
10088 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
10090 hr = IDirect3DDevice9_BeginScene(device);
10091 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
10092 if(SUCCEEDED(hr))
10094 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
10095 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
10097 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
10098 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10099 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
10100 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10102 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
10103 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10104 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
10105 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10107 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
10108 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10109 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
10110 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10112 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
10113 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
10114 hr = IDirect3DDevice9_EndScene(device);
10115 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
10117 /* set all StreamSource && StreamSourceFreq back to default */
10118 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
10119 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10120 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
10121 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10122 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
10123 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10124 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
10125 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10126 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
10127 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10128 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
10129 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10132 hr = IDirect3DVertexDeclaration9_Release(pDecl);
10133 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
10135 color = getPixelColor(device, 160, 360);
10136 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
10137 color = getPixelColor(device, 480, 360);
10138 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
10139 color = getPixelColor(device, 480, 120);
10140 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
10141 color = getPixelColor(device, 160, 120);
10142 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
10144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10145 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
10148 hr = IDirect3DDevice9_SetIndices(device, NULL);
10149 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
10151 out:
10152 if(vb) IDirect3DVertexBuffer9_Release(vb);
10153 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
10154 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
10155 if(ib)IDirect3DIndexBuffer9_Release(ib);
10156 if(shader)IDirect3DVertexShader9_Release(shader);
10159 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
10160 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
10161 IDirect3DTexture9 *dsttex = NULL;
10162 HRESULT hr;
10163 DWORD color;
10164 D3DRECT r1 = {0, 0, 50, 50 };
10165 D3DRECT r2 = {50, 0, 100, 50 };
10166 D3DRECT r3 = {50, 50, 100, 100};
10167 D3DRECT r4 = {0, 50, 50, 100};
10168 const float quad[] = {
10169 -1.0, -1.0, 0.1, 0.0, 0.0,
10170 1.0, -1.0, 0.1, 1.0, 0.0,
10171 -1.0, 1.0, 0.1, 0.0, 1.0,
10172 1.0, 1.0, 0.1, 1.0, 1.0,
10175 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10176 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
10178 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
10179 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
10180 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
10181 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
10183 if(!src || !dsttex) {
10184 skip("One or more test resources could not be created\n");
10185 goto cleanup;
10188 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
10189 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
10191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
10192 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10194 /* Clear the StretchRect destination for debugging */
10195 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
10196 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10197 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10200 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
10201 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10203 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10204 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10205 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10207 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10208 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10209 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
10210 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10212 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
10213 * the target -> texture GL blit path
10215 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
10216 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
10217 IDirect3DSurface9_Release(dst);
10219 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10220 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10222 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
10223 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10224 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10225 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10226 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10227 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10228 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10229 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10231 hr = IDirect3DDevice9_BeginScene(device);
10232 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
10233 if(SUCCEEDED(hr)) {
10234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10235 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
10236 hr = IDirect3DDevice9_EndScene(device);
10237 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
10240 color = getPixelColor(device, 160, 360);
10241 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
10242 color = getPixelColor(device, 480, 360);
10243 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
10244 color = getPixelColor(device, 480, 120);
10245 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
10246 color = getPixelColor(device, 160, 120);
10247 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
10248 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10249 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10251 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10252 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10253 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10254 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10256 cleanup:
10257 if(src) IDirect3DSurface9_Release(src);
10258 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
10259 if(dsttex) IDirect3DTexture9_Release(dsttex);
10262 static void texop_test(IDirect3DDevice9 *device)
10264 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10265 IDirect3DTexture9 *texture = NULL;
10266 D3DLOCKED_RECT locked_rect;
10267 D3DCOLOR color;
10268 D3DCAPS9 caps;
10269 HRESULT hr;
10270 unsigned i;
10272 static const struct {
10273 float x, y, z;
10274 float s, t;
10275 D3DCOLOR diffuse;
10276 } quad[] = {
10277 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10278 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10279 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10280 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10283 static const D3DVERTEXELEMENT9 decl_elements[] = {
10284 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10285 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10286 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10287 D3DDECL_END()
10290 static const struct {
10291 D3DTEXTUREOP op;
10292 const char *name;
10293 DWORD caps_flag;
10294 D3DCOLOR result;
10295 } test_data[] = {
10296 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10297 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10298 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10299 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10300 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10301 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10302 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10303 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10304 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10305 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10306 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10307 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10308 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10309 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10310 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10311 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10312 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10313 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10314 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10315 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10316 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10317 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10318 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10321 memset(&caps, 0, sizeof(caps));
10322 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10323 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10325 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10326 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10327 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10328 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10330 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10331 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10332 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10333 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10334 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10335 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10336 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10337 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10338 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10340 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10341 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10342 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10343 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10344 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10345 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10347 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10348 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10351 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10353 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10355 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10357 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10358 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10360 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10362 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10364 skip("tex operation %s not supported\n", test_data[i].name);
10365 continue;
10368 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10369 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10371 hr = IDirect3DDevice9_BeginScene(device);
10372 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10375 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10377 hr = IDirect3DDevice9_EndScene(device);
10378 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10380 color = getPixelColor(device, 320, 240);
10381 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10382 test_data[i].name, color, test_data[i].result);
10384 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10385 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10388 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10389 IDirect3DTexture9_Release(texture);
10390 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10393 static void yuv_color_test(IDirect3DDevice9 *device) {
10394 HRESULT hr;
10395 IDirect3DSurface9 *surface = NULL, *target = NULL;
10396 unsigned int fmt, i;
10397 D3DFORMAT format;
10398 const char *fmt_string;
10399 D3DLOCKED_RECT lr;
10400 IDirect3D9 *d3d;
10401 HRESULT color;
10402 DWORD ref_color_left, ref_color_right;
10404 struct {
10405 DWORD in; /* The input color */
10406 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10407 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10408 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10409 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10410 } test_data[] = {
10411 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10412 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10413 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10414 * that
10416 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10417 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10418 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10419 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10420 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10421 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10422 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10423 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10424 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10425 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10426 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10427 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10428 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10429 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10431 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10432 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10433 { 0xff80ff80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10434 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10437 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10438 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10439 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10440 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10442 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10443 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10445 for(fmt = 0; fmt < 2; fmt++) {
10446 if(fmt == 0) {
10447 format = D3DFMT_UYVY;
10448 fmt_string = "D3DFMT_UYVY";
10449 } else {
10450 format = D3DFMT_YUY2;
10451 fmt_string = "D3DFMT_YUY2";
10454 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10455 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10457 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10458 D3DRTYPE_SURFACE, format) != D3D_OK) {
10459 skip("%s is not supported\n", fmt_string);
10460 continue;
10463 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1
10464 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
10465 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
10466 * second luminance value, resulting in an incorrect color in the right pixel. */
10467 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10468 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10470 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10471 if(fmt == 0) {
10472 ref_color_left = test_data[i].uyvy_left;
10473 ref_color_right = test_data[i].uyvy_right;
10474 } else {
10475 ref_color_left = test_data[i].yuy2_left;
10476 ref_color_right = test_data[i].yuy2_right;
10479 memset(&lr, 0, sizeof(lr));
10480 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10481 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10482 ((DWORD *) lr.pBits)[0] = test_data[i].in;
10483 ((DWORD *) lr.pBits)[1] = 0x00800080;
10484 hr = IDirect3DSurface9_UnlockRect(surface);
10485 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10487 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10488 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10489 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10490 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10492 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10493 * prevent running into precision problems, read a far left and far right pixel. In the future we may
10494 * want to add tests for the filtered pixels as well.
10496 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10497 * differently, so we need a max diff of 18
10499 color = getPixelColor(device, 1, 240);
10500 ok(color_match(color, ref_color_left, 18),
10501 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10502 test_data[i].in, color, ref_color_left, fmt_string);
10503 color = getPixelColor(device, 318, 240);
10504 ok(color_match(color, ref_color_right, 18),
10505 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10506 test_data[i].in, color, ref_color_right, fmt_string);
10507 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10508 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10510 IDirect3DSurface9_Release(surface);
10513 IDirect3DSurface9_Release(target);
10514 IDirect3D9_Release(d3d);
10517 static void texop_range_test(IDirect3DDevice9 *device)
10519 static const struct {
10520 float x, y, z;
10521 D3DCOLOR diffuse;
10522 } quad[] = {
10523 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10524 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10525 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10526 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10528 HRESULT hr;
10529 IDirect3DTexture9 *texture;
10530 D3DLOCKED_RECT locked_rect;
10531 D3DCAPS9 caps;
10532 DWORD color;
10534 /* We need ADD and SUBTRACT operations */
10535 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10536 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10537 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10538 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10539 return;
10541 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10542 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10543 return;
10546 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10547 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10548 /* Stage 1: result = diffuse(=1.0) + diffuse
10549 * stage 2: result = result - tfactor(= 0.5)
10551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10552 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10554 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10555 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10556 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10557 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10558 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10559 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10560 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10561 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10562 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10563 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10564 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10566 hr = IDirect3DDevice9_BeginScene(device);
10567 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10569 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10570 hr = IDirect3DDevice9_EndScene(device);
10571 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10573 color = getPixelColor(device, 320, 240);
10574 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10575 color);
10576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10577 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10579 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10580 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10581 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10582 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10583 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10584 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10585 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10586 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10587 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10589 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10590 * stage 2: result = result + diffuse(1.0)
10592 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10593 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10594 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10595 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10596 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10597 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10598 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10599 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10600 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10601 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10602 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10603 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10604 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10605 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10607 hr = IDirect3DDevice9_BeginScene(device);
10608 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10610 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10611 hr = IDirect3DDevice9_EndScene(device);
10612 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10614 color = getPixelColor(device, 320, 240);
10615 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10616 color);
10617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10618 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10620 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10621 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10622 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10623 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10624 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10625 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10626 IDirect3DTexture9_Release(texture);
10629 static void alphareplicate_test(IDirect3DDevice9 *device) {
10630 struct vertex quad[] = {
10631 { -1.0, -1.0, 0.1, 0x80ff00ff },
10632 { 1.0, -1.0, 0.1, 0x80ff00ff },
10633 { -1.0, 1.0, 0.1, 0x80ff00ff },
10634 { 1.0, 1.0, 0.1, 0x80ff00ff },
10636 HRESULT hr;
10637 DWORD color;
10639 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10640 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10642 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10643 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10645 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10647 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10648 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10650 hr = IDirect3DDevice9_BeginScene(device);
10651 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10652 if(SUCCEEDED(hr)) {
10653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10654 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10655 hr = IDirect3DDevice9_EndScene(device);
10656 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10659 color = getPixelColor(device, 320, 240);
10660 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10661 color);
10662 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10663 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10665 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10666 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10670 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10671 HRESULT hr;
10672 D3DCAPS9 caps;
10673 DWORD color;
10674 struct vertex quad[] = {
10675 { -1.0, -1.0, 0.1, 0x408080c0 },
10676 { 1.0, -1.0, 0.1, 0x408080c0 },
10677 { -1.0, 1.0, 0.1, 0x408080c0 },
10678 { 1.0, 1.0, 0.1, 0x408080c0 },
10681 memset(&caps, 0, sizeof(caps));
10682 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10683 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10684 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10685 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10686 return;
10689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10690 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10692 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10693 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10695 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10696 * mov r0.a, diffuse.a
10697 * mov r0, r0.a
10699 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10700 * 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
10701 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10703 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10704 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10705 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10706 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10707 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10708 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10709 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10710 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10711 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10712 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10713 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10714 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10715 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10717 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10718 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10720 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10722 hr = IDirect3DDevice9_BeginScene(device);
10723 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10724 if(SUCCEEDED(hr)) {
10725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10726 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10727 hr = IDirect3DDevice9_EndScene(device);
10728 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10731 color = getPixelColor(device, 320, 240);
10732 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10733 color);
10734 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10735 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10737 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10738 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10739 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10740 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10741 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10742 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10745 static void zwriteenable_test(IDirect3DDevice9 *device) {
10746 HRESULT hr;
10747 DWORD color;
10748 struct vertex quad1[] = {
10749 { -1.0, -1.0, 0.1, 0x00ff0000},
10750 { -1.0, 1.0, 0.1, 0x00ff0000},
10751 { 1.0, -1.0, 0.1, 0x00ff0000},
10752 { 1.0, 1.0, 0.1, 0x00ff0000},
10754 struct vertex quad2[] = {
10755 { -1.0, -1.0, 0.9, 0x0000ff00},
10756 { -1.0, 1.0, 0.9, 0x0000ff00},
10757 { 1.0, -1.0, 0.9, 0x0000ff00},
10758 { 1.0, 1.0, 0.9, 0x0000ff00},
10761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10762 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10765 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10767 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10769 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10771 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10773 hr = IDirect3DDevice9_BeginScene(device);
10774 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10775 if(SUCCEEDED(hr)) {
10776 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10777 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10778 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10779 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10780 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10781 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10784 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10786 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10787 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10788 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10790 hr = IDirect3DDevice9_EndScene(device);
10791 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10794 color = getPixelColor(device, 320, 240);
10795 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10796 color);
10797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10798 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10801 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10804 static void alphatest_test(IDirect3DDevice9 *device) {
10805 #define ALPHATEST_PASSED 0x0000ff00
10806 #define ALPHATEST_FAILED 0x00ff0000
10807 struct {
10808 D3DCMPFUNC func;
10809 DWORD color_less;
10810 DWORD color_equal;
10811 DWORD color_greater;
10812 } testdata[] = {
10813 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10814 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10815 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10816 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10817 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10818 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10819 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10820 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10822 unsigned int i, j;
10823 HRESULT hr;
10824 DWORD color;
10825 struct vertex quad[] = {
10826 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10827 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10828 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10829 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10831 D3DCAPS9 caps;
10833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10834 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10835 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10836 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10838 for (j = 0; j < 2; ++j)
10840 if (j == 1)
10842 /* Try a pixel shader instead of fixed function. The wined3d code
10843 * may emulate the alpha test either for performance reasons
10844 * (floating point RTs) or to work around driver bugs (GeForce
10845 * 7x00 cards on MacOS). There may be a different codepath for ffp
10846 * and shader in this case, and the test should cover both. */
10847 IDirect3DPixelShader9 *ps;
10848 static const DWORD shader_code[] =
10850 0xffff0101, /* ps_1_1 */
10851 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10852 0x0000ffff /* end */
10854 memset(&caps, 0, sizeof(caps));
10855 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10856 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10857 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10858 break;
10861 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10862 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10863 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10865 IDirect3DPixelShader9_Release(ps);
10868 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10870 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10872 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10873 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10875 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10876 hr = IDirect3DDevice9_BeginScene(device);
10877 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10878 if(SUCCEEDED(hr)) {
10879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10880 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10881 hr = IDirect3DDevice9_EndScene(device);
10882 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10884 color = getPixelColor(device, 320, 240);
10885 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10886 color, testdata[i].color_less, testdata[i].func);
10887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10888 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10890 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10891 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10894 hr = IDirect3DDevice9_BeginScene(device);
10895 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10896 if(SUCCEEDED(hr)) {
10897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10898 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10899 hr = IDirect3DDevice9_EndScene(device);
10900 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10902 color = getPixelColor(device, 320, 240);
10903 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10904 color, testdata[i].color_equal, testdata[i].func);
10905 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10906 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10908 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10909 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10911 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10912 hr = IDirect3DDevice9_BeginScene(device);
10913 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10914 if(SUCCEEDED(hr)) {
10915 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10916 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10917 hr = IDirect3DDevice9_EndScene(device);
10918 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10920 color = getPixelColor(device, 320, 240);
10921 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10922 color, testdata[i].color_greater, testdata[i].func);
10923 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10924 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10929 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10930 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10931 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10934 static void sincos_test(IDirect3DDevice9 *device)
10936 static const DWORD sin_shader_code[] =
10938 0xfffe0200, /* vs_2_0 */
10939 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10940 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10941 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10942 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10943 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10944 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10945 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10946 0x0000ffff /* end */
10948 static const DWORD cos_shader_code[] =
10950 0xfffe0200, /* vs_2_0 */
10951 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10952 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10953 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10954 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10955 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10956 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10957 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10958 0x0000ffff /* end */
10960 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10961 HRESULT hr;
10962 struct {
10963 float x, y, z;
10964 } data[1280];
10965 unsigned int i;
10966 float sincosc1[4] = {D3DSINCOSCONST1};
10967 float sincosc2[4] = {D3DSINCOSCONST2};
10969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10970 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10972 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10973 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10974 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10975 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10976 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10977 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10978 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10979 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10980 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10981 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10983 /* Generate a point from -1 to 1 every 0.5 pixels */
10984 for(i = 0; i < 1280; i++) {
10985 data[i].x = (-640.0 + i) / 640.0;
10986 data[i].y = 0.0;
10987 data[i].z = 0.1;
10990 hr = IDirect3DDevice9_BeginScene(device);
10991 if(SUCCEEDED(hr)) {
10992 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10993 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10995 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10997 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10998 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10999 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
11000 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
11002 hr = IDirect3DDevice9_EndScene(device);
11003 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11006 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
11007 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
11009 IDirect3DDevice9_SetVertexShader(device, NULL);
11010 IDirect3DVertexShader9_Release(sin_shader);
11011 IDirect3DVertexShader9_Release(cos_shader);
11014 static void loop_index_test(IDirect3DDevice9 *device)
11016 static const DWORD shader_code[] =
11018 0xfffe0200, /* vs_2_0 */
11019 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11020 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
11021 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
11022 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
11023 0x0000001d, /* endloop */
11024 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11025 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
11026 0x0000ffff /* END */
11028 IDirect3DVertexShader9 *shader;
11029 HRESULT hr;
11030 DWORD color;
11031 const float quad[] = {
11032 -1.0, -1.0, 0.1,
11033 1.0, -1.0, 0.1,
11034 -1.0, 1.0, 0.1,
11035 1.0, 1.0, 0.1
11037 const float zero[4] = {0, 0, 0, 0};
11038 const float one[4] = {1, 1, 1, 1};
11039 int i0[4] = {2, 10, -3, 0};
11040 float values[4];
11042 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11043 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
11044 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11045 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
11046 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11047 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
11049 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
11051 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
11052 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11053 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
11054 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11055 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
11056 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11057 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
11058 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11059 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
11060 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11061 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
11062 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11063 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
11064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11065 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
11066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11067 values[0] = 1.0;
11068 values[1] = 1.0;
11069 values[2] = 0.0;
11070 values[3] = 0.0;
11071 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
11072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11073 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
11074 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11075 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
11076 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11077 values[0] = -1.0;
11078 values[1] = 0.0;
11079 values[2] = 0.0;
11080 values[3] = 0.0;
11081 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
11082 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11083 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
11084 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11085 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
11086 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11087 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
11088 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11089 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
11090 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11092 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
11093 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
11095 hr = IDirect3DDevice9_BeginScene(device);
11096 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
11097 if(SUCCEEDED(hr))
11099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11100 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
11101 hr = IDirect3DDevice9_EndScene(device);
11102 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
11104 color = getPixelColor(device, 320, 240);
11105 ok(color_match(color, 0x0000ff00, 1),
11106 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
11107 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11108 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11110 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
11112 IDirect3DVertexShader9_Release(shader);
11115 static void sgn_test(IDirect3DDevice9 *device)
11117 static const DWORD shader_code[] =
11119 0xfffe0200, /* vs_2_0 */
11120 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
11121 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
11122 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
11123 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11124 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
11125 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
11126 0x0000ffff /* end */
11128 IDirect3DVertexShader9 *shader;
11129 HRESULT hr;
11130 DWORD color;
11131 const float quad[] = {
11132 -1.0, -1.0, 0.1,
11133 1.0, -1.0, 0.1,
11134 -1.0, 1.0, 0.1,
11135 1.0, 1.0, 0.1
11138 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11139 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
11140 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11141 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
11142 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11143 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11144 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
11145 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
11147 hr = IDirect3DDevice9_BeginScene(device);
11148 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
11149 if(SUCCEEDED(hr))
11151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11152 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
11153 hr = IDirect3DDevice9_EndScene(device);
11154 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
11156 color = getPixelColor(device, 320, 240);
11157 ok(color_match(color, 0x008000ff, 1),
11158 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
11159 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11160 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11162 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11163 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
11164 IDirect3DVertexShader9_Release(shader);
11167 static void viewport_test(IDirect3DDevice9 *device) {
11168 HRESULT hr;
11169 DWORD color;
11170 D3DVIEWPORT9 vp, old_vp;
11171 BOOL draw_failed = TRUE;
11172 const float quad[] =
11174 -0.5, -0.5, 0.1,
11175 0.5, -0.5, 0.1,
11176 -0.5, 0.5, 0.1,
11177 0.5, 0.5, 0.1
11180 memset(&old_vp, 0, sizeof(old_vp));
11181 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
11182 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
11184 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
11185 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
11187 /* Test a viewport with Width and Height bigger than the surface dimensions
11189 * TODO: Test Width < surface.width, but X + Width > surface.width
11190 * TODO: Test Width < surface.width, what happens with the height?
11192 * The expected behavior is that the viewport behaves like the "default"
11193 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
11194 * MinZ = 0.0, MaxZ = 1.0.
11196 * Starting with Windows 7 the behavior among driver versions is not
11197 * consistent. The SetViewport call is accepted on all drivers. Some
11198 * drivers(older nvidia ones) refuse to draw and return an error. Newer
11199 * nvidia drivers draw, but use the actual values in the viewport and only
11200 * display the upper left part on the surface.
11202 memset(&vp, 0, sizeof(vp));
11203 vp.X = 0;
11204 vp.Y = 0;
11205 vp.Width = 10000;
11206 vp.Height = 10000;
11207 vp.MinZ = 0.0;
11208 vp.MaxZ = 0.0;
11209 hr = IDirect3DDevice9_SetViewport(device, &vp);
11210 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
11212 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11213 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
11214 hr = IDirect3DDevice9_BeginScene(device);
11215 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
11216 if(SUCCEEDED(hr))
11218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11219 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
11220 draw_failed = FAILED(hr);
11221 hr = IDirect3DDevice9_EndScene(device);
11222 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
11225 if(!draw_failed)
11227 color = getPixelColor(device, 158, 118);
11228 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
11229 color = getPixelColor(device, 162, 118);
11230 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
11231 color = getPixelColor(device, 158, 122);
11232 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
11233 color = getPixelColor(device, 162, 122);
11234 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
11236 color = getPixelColor(device, 478, 358);
11237 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
11238 color = getPixelColor(device, 482, 358);
11239 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
11240 color = getPixelColor(device, 478, 362);
11241 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
11242 color = getPixelColor(device, 482, 362);
11243 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
11246 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11247 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11249 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
11250 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
11253 /* This test tests depth clamping / clipping behaviour:
11254 * - With software vertex processing, depth values are clamped to the
11255 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
11256 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
11257 * same as regular vertices here.
11258 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
11259 * Normal vertices are always clipped. Pretransformed vertices are
11260 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
11261 * - The viewport's MinZ/MaxZ is irrelevant for this.
11263 static void depth_clamp_test(IDirect3DDevice9 *device)
11265 const struct tvertex quad1[] =
11267 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
11268 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
11269 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
11270 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
11272 const struct tvertex quad2[] =
11274 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11275 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11276 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11277 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11279 const struct tvertex quad3[] =
11281 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
11282 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
11283 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
11284 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
11286 const struct tvertex quad4[] =
11288 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
11289 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
11290 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11291 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11293 const struct vertex quad5[] =
11295 { -0.5f, 0.5f, 10.0f, 0xff14f914},
11296 { 0.5f, 0.5f, 10.0f, 0xff14f914},
11297 { -0.5f, -0.5f, 10.0f, 0xff14f914},
11298 { 0.5f, -0.5f, 10.0f, 0xff14f914},
11300 const struct vertex quad6[] =
11302 { -1.0f, 0.5f, 10.0f, 0xfff91414},
11303 { 1.0f, 0.5f, 10.0f, 0xfff91414},
11304 { -1.0f, 0.25f, 10.0f, 0xfff91414},
11305 { 1.0f, 0.25f, 10.0f, 0xfff91414},
11308 D3DVIEWPORT9 vp;
11309 D3DCOLOR color;
11310 D3DCAPS9 caps;
11311 HRESULT hr;
11313 vp.X = 0;
11314 vp.Y = 0;
11315 vp.Width = 640;
11316 vp.Height = 480;
11317 vp.MinZ = 0.0;
11318 vp.MaxZ = 7.5;
11320 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11321 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11323 hr = IDirect3DDevice9_SetViewport(device, &vp);
11324 if(FAILED(hr))
11326 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11327 * the tests because the 7.5 is just intended to show that it doesn't have
11328 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11329 * viewport and continue.
11331 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11332 vp.MaxZ = 1.0;
11333 hr = IDirect3DDevice9_SetViewport(device, &vp);
11335 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11338 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11341 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11343 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11345 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11347 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11349 hr = IDirect3DDevice9_BeginScene(device);
11350 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11353 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11358 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11361 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11363 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11364 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11366 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11371 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11372 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11375 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11378 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11381 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11383 hr = IDirect3DDevice9_EndScene(device);
11384 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11386 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11388 color = getPixelColor(device, 75, 75);
11389 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11390 color = getPixelColor(device, 150, 150);
11391 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11392 color = getPixelColor(device, 320, 240);
11393 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11394 color = getPixelColor(device, 320, 330);
11395 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11396 color = getPixelColor(device, 320, 330);
11397 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11399 else
11401 color = getPixelColor(device, 75, 75);
11402 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11403 color = getPixelColor(device, 150, 150);
11404 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11405 color = getPixelColor(device, 320, 240);
11406 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11407 color = getPixelColor(device, 320, 330);
11408 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11409 color = getPixelColor(device, 320, 330);
11410 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11413 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11414 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11416 vp.MinZ = 0.0;
11417 vp.MaxZ = 1.0;
11418 hr = IDirect3DDevice9_SetViewport(device, &vp);
11419 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11422 static void depth_bounds_test(IDirect3DDevice9 *device)
11424 const struct tvertex quad1[] =
11426 { 0, 0, 0.0f, 1, 0xfff9e814},
11427 { 640, 0, 0.0f, 1, 0xfff9e814},
11428 { 0, 480, 1.0f, 1, 0xfff9e814},
11429 { 640, 480, 1.0f, 1, 0xfff9e814},
11431 const struct tvertex quad2[] =
11433 { 0, 0, 0.6f, 1, 0xff002b7f},
11434 { 640, 0, 0.6f, 1, 0xff002b7f},
11435 { 0, 480, 0.6f, 1, 0xff002b7f},
11436 { 640, 480, 0.6f, 1, 0xff002b7f},
11438 const struct tvertex quad3[] =
11440 { 0, 100, 0.6f, 1, 0xfff91414},
11441 { 640, 100, 0.6f, 1, 0xfff91414},
11442 { 0, 160, 0.6f, 1, 0xfff91414},
11443 { 640, 160, 0.6f, 1, 0xfff91414},
11446 union {
11447 DWORD d;
11448 float f;
11449 } tmpvalue;
11451 IDirect3D9 *d3d = NULL;
11452 IDirect3DSurface9 *offscreen_surface = NULL;
11453 D3DCOLOR color;
11454 HRESULT hr;
11456 IDirect3DDevice9_GetDirect3D(device, &d3d);
11457 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11458 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11459 skip("No NVDB (depth bounds test) support\n");
11460 IDirect3D9_Release(d3d);
11461 return;
11463 IDirect3D9_Release(d3d);
11465 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11466 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11467 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11468 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11471 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11474 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11476 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11478 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11480 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11483 hr = IDirect3DDevice9_BeginScene(device);
11484 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11486 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11487 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11490 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11493 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11495 tmpvalue.f = 0.625;
11496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11497 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11499 tmpvalue.f = 0.75;
11500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11501 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11504 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11506 tmpvalue.f = 0.75;
11507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11508 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11511 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11513 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11514 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11516 hr = IDirect3DDevice9_EndScene(device);
11517 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11519 color = getPixelColor(device, 150, 130);
11520 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11521 color = getPixelColor(device, 150, 200);
11522 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11523 color = getPixelColor(device, 150, 300-5);
11524 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11525 color = getPixelColor(device, 150, 300+5);
11526 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11527 color = getPixelColor(device, 150, 330);
11528 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11529 color = getPixelColor(device, 150, 360-5);
11530 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11531 color = getPixelColor(device, 150, 360+5);
11532 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11534 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11535 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11538 static void depth_buffer_test(IDirect3DDevice9 *device)
11540 static const struct vertex quad1[] =
11542 { -1.0, 1.0, 0.33f, 0xff00ff00},
11543 { 1.0, 1.0, 0.33f, 0xff00ff00},
11544 { -1.0, -1.0, 0.33f, 0xff00ff00},
11545 { 1.0, -1.0, 0.33f, 0xff00ff00},
11547 static const struct vertex quad2[] =
11549 { -1.0, 1.0, 0.50f, 0xffff00ff},
11550 { 1.0, 1.0, 0.50f, 0xffff00ff},
11551 { -1.0, -1.0, 0.50f, 0xffff00ff},
11552 { 1.0, -1.0, 0.50f, 0xffff00ff},
11554 static const struct vertex quad3[] =
11556 { -1.0, 1.0, 0.66f, 0xffff0000},
11557 { 1.0, 1.0, 0.66f, 0xffff0000},
11558 { -1.0, -1.0, 0.66f, 0xffff0000},
11559 { 1.0, -1.0, 0.66f, 0xffff0000},
11561 static const DWORD expected_colors[4][4] =
11563 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11564 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11565 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11566 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11569 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11570 unsigned int i, j;
11571 D3DVIEWPORT9 vp;
11572 D3DCOLOR color;
11573 HRESULT hr;
11575 vp.X = 0;
11576 vp.Y = 0;
11577 vp.Width = 640;
11578 vp.Height = 480;
11579 vp.MinZ = 0.0;
11580 vp.MaxZ = 1.0;
11582 hr = IDirect3DDevice9_SetViewport(device, &vp);
11583 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11586 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11587 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11588 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11589 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11590 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11592 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11593 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11594 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11596 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11597 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11598 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11599 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11600 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11601 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11602 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11603 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11604 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11605 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11606 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11608 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11609 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11610 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11611 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11613 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11614 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11616 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11618 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11619 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11621 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11623 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11624 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11625 hr = IDirect3DDevice9_BeginScene(device);
11626 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11628 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11629 hr = IDirect3DDevice9_EndScene(device);
11630 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11632 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11633 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11636 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11638 hr = IDirect3DDevice9_BeginScene(device);
11639 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11641 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11643 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11644 hr = IDirect3DDevice9_EndScene(device);
11645 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11647 for (i = 0; i < 4; ++i)
11649 for (j = 0; j < 4; ++j)
11651 unsigned int x = 80 * ((2 * j) + 1);
11652 unsigned int y = 60 * ((2 * i) + 1);
11653 color = getPixelColor(device, x, y);
11654 ok(color_match(color, expected_colors[i][j], 0),
11655 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11660 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11662 IDirect3DSurface9_Release(backbuffer);
11663 IDirect3DSurface9_Release(rt3);
11664 IDirect3DSurface9_Release(rt2);
11665 IDirect3DSurface9_Release(rt1);
11668 /* Test that partial depth copies work the way they're supposed to. The clear
11669 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11670 * the following draw should only copy back the part that was modified. */
11671 static void depth_buffer2_test(IDirect3DDevice9 *device)
11673 static const struct vertex quad[] =
11675 { -1.0, 1.0, 0.66f, 0xffff0000},
11676 { 1.0, 1.0, 0.66f, 0xffff0000},
11677 { -1.0, -1.0, 0.66f, 0xffff0000},
11678 { 1.0, -1.0, 0.66f, 0xffff0000},
11681 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11682 unsigned int i, j;
11683 D3DVIEWPORT9 vp;
11684 D3DCOLOR color;
11685 HRESULT hr;
11687 vp.X = 0;
11688 vp.Y = 0;
11689 vp.Width = 640;
11690 vp.Height = 480;
11691 vp.MinZ = 0.0;
11692 vp.MaxZ = 1.0;
11694 hr = IDirect3DDevice9_SetViewport(device, &vp);
11695 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11698 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11700 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11702 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11703 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11704 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11705 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11706 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11708 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11709 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11710 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11711 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11712 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11713 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11714 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11715 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11717 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11718 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11719 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11720 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11722 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11723 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11724 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11725 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11727 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11728 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11729 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11730 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11732 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11733 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11736 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11738 hr = IDirect3DDevice9_BeginScene(device);
11739 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11741 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11742 hr = IDirect3DDevice9_EndScene(device);
11743 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11745 for (i = 0; i < 4; ++i)
11747 for (j = 0; j < 4; ++j)
11749 unsigned int x = 80 * ((2 * j) + 1);
11750 unsigned int y = 60 * ((2 * i) + 1);
11751 color = getPixelColor(device, x, y);
11752 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11753 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11757 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11758 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11760 IDirect3DSurface9_Release(backbuffer);
11761 IDirect3DSurface9_Release(rt2);
11762 IDirect3DSurface9_Release(rt1);
11765 static void depth_blit_test(IDirect3DDevice9 *device)
11767 static const struct vertex quad1[] =
11769 { -1.0, 1.0, 0.33f, 0xff00ff00},
11770 { 1.0, 1.0, 0.33f, 0xff00ff00},
11771 { -1.0, -1.0, 0.33f, 0xff00ff00},
11772 { 1.0, -1.0, 0.33f, 0xff00ff00},
11774 static const struct vertex quad2[] =
11776 { -1.0, 1.0, 0.66f, 0xff0000ff},
11777 { 1.0, 1.0, 0.66f, 0xff0000ff},
11778 { -1.0, -1.0, 0.66f, 0xff0000ff},
11779 { 1.0, -1.0, 0.66f, 0xff0000ff},
11781 static const DWORD expected_colors[4][4] =
11783 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11784 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11785 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11786 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11789 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11790 RECT src_rect, dst_rect;
11791 unsigned int i, j;
11792 D3DVIEWPORT9 vp;
11793 D3DCOLOR color;
11794 HRESULT hr;
11796 vp.X = 0;
11797 vp.Y = 0;
11798 vp.Width = 640;
11799 vp.Height = 480;
11800 vp.MinZ = 0.0;
11801 vp.MaxZ = 1.0;
11803 hr = IDirect3DDevice9_SetViewport(device, &vp);
11804 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11806 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11807 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11808 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11809 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11810 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11811 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11812 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11813 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11814 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11815 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11818 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11820 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11822 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11823 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11824 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11827 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11828 SetRect(&dst_rect, 0, 0, 480, 360);
11829 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11830 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11831 SetRect(&dst_rect, 0, 0, 320, 240);
11832 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11833 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11835 /* Partial blit. */
11836 SetRect(&src_rect, 0, 0, 320, 240);
11837 SetRect(&dst_rect, 0, 0, 320, 240);
11838 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11839 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11840 /* Flipped. */
11841 SetRect(&src_rect, 0, 0, 640, 480);
11842 SetRect(&dst_rect, 0, 480, 640, 0);
11843 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11844 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11845 /* Full, explicit. */
11846 SetRect(&src_rect, 0, 0, 640, 480);
11847 SetRect(&dst_rect, 0, 0, 640, 480);
11848 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11849 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11850 /* Filtered blit. */
11851 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11852 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11853 /* Depth -> color blit.*/
11854 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11855 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11856 IDirect3DSurface9_Release(backbuffer);
11857 /* Full surface, different sizes */
11858 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11859 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11860 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11861 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11863 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11864 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11865 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11866 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11867 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11868 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11871 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11872 hr = IDirect3DDevice9_BeginScene(device);
11873 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11874 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11875 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11877 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11878 hr = IDirect3DDevice9_EndScene(device);
11879 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11881 for (i = 0; i < 4; ++i)
11883 for (j = 0; j < 4; ++j)
11885 unsigned int x = 80 * ((2 * j) + 1);
11886 unsigned int y = 60 * ((2 * i) + 1);
11887 color = getPixelColor(device, x, y);
11888 ok(color_match(color, expected_colors[i][j], 0),
11889 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11894 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11896 IDirect3DSurface9_Release(ds3);
11897 IDirect3DSurface9_Release(ds2);
11898 IDirect3DSurface9_Release(ds1);
11901 static void intz_test(IDirect3DDevice9 *device)
11903 static const DWORD ps_code[] =
11905 0xffff0200, /* ps_2_0 */
11906 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11907 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11908 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11909 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11910 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11911 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11912 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11913 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11914 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11915 0x0000ffff, /* end */
11917 struct
11919 float x, y, z;
11920 float s, t, p, q;
11922 quad[] =
11924 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11925 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11926 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11927 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11929 half_quad_1[] =
11931 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11932 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11933 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11934 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11936 half_quad_2[] =
11938 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11939 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11940 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11941 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11943 struct
11945 UINT x, y;
11946 D3DCOLOR color;
11948 expected_colors[] =
11950 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11951 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11952 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11953 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11954 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11955 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11956 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11957 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11960 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11961 IDirect3DTexture9 *texture;
11962 IDirect3DPixelShader9 *ps;
11963 IDirect3DSurface9 *ds;
11964 IDirect3D9 *d3d9;
11965 D3DCAPS9 caps;
11966 HRESULT hr;
11967 UINT i;
11969 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11970 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11971 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11973 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11974 return;
11976 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11978 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11979 return;
11982 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11983 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11985 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11986 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11987 if (FAILED(hr))
11989 skip("No INTZ support, skipping INTZ test.\n");
11990 return;
11993 IDirect3D9_Release(d3d9);
11995 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11996 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11997 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11998 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12000 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
12001 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
12002 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12003 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12004 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12005 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12006 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12007 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12009 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12010 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12012 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12014 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12016 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12018 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12020 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12021 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12022 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12023 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12024 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12025 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12026 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12027 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12028 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12029 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12031 /* Render offscreen, using the INTZ texture as depth buffer */
12032 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12033 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12034 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12035 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12036 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12037 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12038 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12039 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12041 /* Setup the depth/stencil surface. */
12042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12043 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12045 hr = IDirect3DDevice9_BeginScene(device);
12046 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12048 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12049 hr = IDirect3DDevice9_EndScene(device);
12050 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12052 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12053 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12054 IDirect3DSurface9_Release(ds);
12055 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12056 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12057 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12058 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12059 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12060 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12062 /* Read the depth values back. */
12063 hr = IDirect3DDevice9_BeginScene(device);
12064 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12066 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12067 hr = IDirect3DDevice9_EndScene(device);
12068 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12070 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12072 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12073 ok(color_match(color, expected_colors[i].color, 1),
12074 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12075 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12078 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12079 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12081 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12082 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12083 IDirect3DTexture9_Release(texture);
12085 /* Render onscreen while using the INTZ texture as depth buffer */
12086 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
12087 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
12088 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12089 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12090 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12091 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12092 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12093 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12095 /* Setup the depth/stencil surface. */
12096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12097 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12099 hr = IDirect3DDevice9_BeginScene(device);
12100 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12101 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12102 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12103 hr = IDirect3DDevice9_EndScene(device);
12104 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12106 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12107 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12108 IDirect3DSurface9_Release(ds);
12109 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12110 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12111 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12112 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12114 /* Read the depth values back. */
12115 hr = IDirect3DDevice9_BeginScene(device);
12116 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12118 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12119 hr = IDirect3DDevice9_EndScene(device);
12120 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12122 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12124 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12125 ok(color_match(color, expected_colors[i].color, 1),
12126 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12127 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12130 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12131 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12133 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12134 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12135 IDirect3DTexture9_Release(texture);
12137 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
12138 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
12139 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
12140 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12141 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12143 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12144 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12145 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12146 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12147 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12148 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12150 /* Setup the depth/stencil surface. */
12151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12152 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12154 hr = IDirect3DDevice9_BeginScene(device);
12155 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
12157 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12158 hr = IDirect3DDevice9_EndScene(device);
12159 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12161 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12162 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12164 hr = IDirect3DDevice9_BeginScene(device);
12165 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
12167 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12168 hr = IDirect3DDevice9_EndScene(device);
12169 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12171 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12172 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12173 IDirect3DSurface9_Release(ds);
12174 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12175 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12176 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12177 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12179 /* Read the depth values back. */
12180 hr = IDirect3DDevice9_BeginScene(device);
12181 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12182 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12183 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12184 hr = IDirect3DDevice9_EndScene(device);
12185 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12187 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12189 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12190 ok(color_match(color, expected_colors[i].color, 1),
12191 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12192 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12195 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12196 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12198 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12199 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12200 IDirect3DSurface9_Release(original_ds);
12201 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12202 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12203 IDirect3DTexture9_Release(texture);
12204 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12205 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12206 IDirect3DPixelShader9_Release(ps);
12208 IDirect3DSurface9_Release(original_rt);
12209 IDirect3DSurface9_Release(rt);
12212 static void shadow_test(IDirect3DDevice9 *device)
12214 static const DWORD ps_code[] =
12216 0xffff0200, /* ps_2_0 */
12217 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12218 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12219 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
12220 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
12221 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12222 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
12223 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
12224 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
12225 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
12226 0x0000ffff, /* end */
12228 struct
12230 D3DFORMAT format;
12231 const char *name;
12233 formats[] =
12235 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
12236 {D3DFMT_D32, "D3DFMT_D32"},
12237 {D3DFMT_D15S1, "D3DFMT_D15S1"},
12238 {D3DFMT_D24S8, "D3DFMT_D24S8"},
12239 {D3DFMT_D24X8, "D3DFMT_D24X8"},
12240 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
12241 {D3DFMT_D16, "D3DFMT_D16"},
12242 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
12243 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
12245 struct
12247 float x, y, z;
12248 float s, t, p, q;
12250 quad[] =
12252 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
12253 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
12254 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
12255 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
12257 struct
12259 UINT x, y;
12260 D3DCOLOR color;
12262 expected_colors[] =
12264 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12265 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12266 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12267 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12268 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12269 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12270 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12271 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12274 IDirect3DSurface9 *original_ds, *original_rt, *rt;
12275 IDirect3DPixelShader9 *ps;
12276 IDirect3D9 *d3d9;
12277 D3DCAPS9 caps;
12278 HRESULT hr;
12279 UINT i;
12281 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12282 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12283 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12285 skip("No pixel shader 2.0 support, skipping shadow test.\n");
12286 return;
12289 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12290 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12291 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12292 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12293 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12294 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12296 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12297 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12298 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12299 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12300 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12302 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12303 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12305 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12307 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12309 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12310 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12311 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12313 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12314 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12315 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12316 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12317 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12318 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12319 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12320 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12321 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12322 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12324 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12326 D3DFORMAT format = formats[i].format;
12327 IDirect3DTexture9 *texture;
12328 IDirect3DSurface9 *ds;
12329 unsigned int j;
12331 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12332 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12333 if (FAILED(hr)) continue;
12335 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12336 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12337 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12339 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12340 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12342 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12343 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12345 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12346 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12348 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12349 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12351 /* Setup the depth/stencil surface. */
12352 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12353 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12355 hr = IDirect3DDevice9_BeginScene(device);
12356 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12358 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12359 hr = IDirect3DDevice9_EndScene(device);
12360 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12362 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12363 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12364 IDirect3DSurface9_Release(ds);
12366 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12367 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12369 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12370 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12372 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12373 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12375 /* Do the actual shadow mapping. */
12376 hr = IDirect3DDevice9_BeginScene(device);
12377 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12379 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12380 hr = IDirect3DDevice9_EndScene(device);
12381 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12383 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12384 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12385 IDirect3DTexture9_Release(texture);
12387 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12389 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12390 ok(color_match(color, expected_colors[j].color, 0),
12391 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12392 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12393 formats[i].name, color);
12396 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12397 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12400 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12401 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12402 IDirect3DPixelShader9_Release(ps);
12404 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12405 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12406 IDirect3DSurface9_Release(original_ds);
12408 IDirect3DSurface9_Release(original_rt);
12409 IDirect3DSurface9_Release(rt);
12411 IDirect3D9_Release(d3d9);
12414 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12416 const struct vertex quad1[] =
12418 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12419 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12420 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
12421 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
12423 const struct vertex quad2[] =
12425 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12426 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12427 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
12428 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
12430 D3DCOLOR color;
12431 HRESULT hr;
12433 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12434 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12436 hr = IDirect3DDevice9_BeginScene(device);
12437 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12439 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12440 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12443 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12445 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12448 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12450 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12452 hr = IDirect3DDevice9_EndScene(device);
12453 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12455 color = getPixelColor(device, 1, 240);
12456 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12457 color = getPixelColor(device, 638, 240);
12458 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12460 color = getPixelColor(device, 1, 241);
12461 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12462 color = getPixelColor(device, 638, 241);
12463 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12466 static void clip_planes_test(IDirect3DDevice9 *device)
12468 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12470 static const DWORD shader_code[] =
12472 0xfffe0200, /* vs_2_0 */
12473 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12474 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12475 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12476 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12477 0x0000ffff /* end */
12479 IDirect3DVertexShader9 *shader;
12481 IDirect3DTexture9 *offscreen = NULL;
12482 IDirect3DSurface9 *offscreen_surface, *original_rt;
12483 HRESULT hr;
12485 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12486 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12489 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12491 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12493 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12495 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12497 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12498 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12499 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12500 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12502 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12504 clip_planes(device, "Onscreen FFP");
12506 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12507 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12508 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12509 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12510 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12511 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12513 clip_planes(device, "Offscreen FFP");
12515 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12516 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12518 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12519 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12520 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12521 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12523 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12524 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12526 clip_planes(device, "Onscreen vertex shader");
12528 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12531 clip_planes(device, "Offscreen vertex shader");
12533 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12534 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12536 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12537 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12538 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12539 IDirect3DVertexShader9_Release(shader);
12540 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12542 IDirect3DSurface9_Release(original_rt);
12543 IDirect3DSurface9_Release(offscreen_surface);
12544 IDirect3DTexture9_Release(offscreen);
12547 static void fp_special_test(IDirect3DDevice9 *device)
12549 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
12550 static const DWORD vs_header[] =
12552 0xfffe0200, /* vs_2_0 */
12553 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12554 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
12555 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12556 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
12559 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
12560 static const DWORD vs_pow[] =
12561 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
12562 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
12563 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
12564 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
12565 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
12566 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
12567 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
12568 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
12569 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
12570 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
12571 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
12573 static const DWORD vs_footer[] =
12575 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
12576 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
12577 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
12578 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
12579 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12580 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
12581 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
12582 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
12583 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12584 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
12585 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
12586 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
12587 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
12588 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
12589 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12590 0x0000ffff, /* end */
12593 static const struct
12595 const char *name;
12596 const DWORD *ops;
12597 DWORD size;
12598 D3DCOLOR r500;
12599 D3DCOLOR r600;
12600 D3DCOLOR nv40;
12601 D3DCOLOR nv50;
12603 vs_body[] =
12605 /* The basic ideas here are:
12606 * 2.0 * +/-INF == +/-INF
12607 * NAN != NAN
12609 * The vertex shader value is written to the red component, with 0.0
12610 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12611 * result in 0x00. The pixel shader value is written to the green
12612 * component, but here 0.0 also results in 0x00. The actual value is
12613 * written to the blue component.
12615 * There are considerable differences between graphics cards in how
12616 * these are handled, but pow and nrm never generate INF or NAN. */
12617 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00},
12618 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff},
12619 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000},
12620 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12621 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00},
12622 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12623 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12624 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12625 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00},
12626 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00},
12627 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00},
12630 static const DWORD ps_code[] =
12632 0xffff0200, /* ps_2_0 */
12633 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12634 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
12635 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
12636 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
12637 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
12638 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
12639 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
12640 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
12641 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
12642 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
12643 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
12644 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
12645 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
12646 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
12647 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
12648 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
12649 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
12650 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
12651 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
12652 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
12653 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
12654 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12655 0x0000ffff, /* end */
12658 struct
12660 float x, y, z;
12661 float s;
12663 quad[] =
12665 { -1.0f, 1.0f, 0.0f, 0.0f},
12666 { 1.0f, 1.0f, 1.0f, 0.0f},
12667 { -1.0f, -1.0f, 0.0f, 0.0f},
12668 { 1.0f, -1.0f, 1.0f, 0.0f},
12671 IDirect3DPixelShader9 *ps;
12672 UINT body_size = 0;
12673 DWORD *vs_code;
12674 D3DCAPS9 caps;
12675 HRESULT hr;
12676 UINT i;
12678 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12679 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12680 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12682 skip("No shader model 2.0 support, skipping floating point specials test.\n");
12683 return;
12686 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12687 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12689 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12690 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12691 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12692 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12695 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12697 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12698 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12700 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12702 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12705 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12706 memcpy(vs_code, vs_header, sizeof(vs_header));
12708 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12710 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12711 IDirect3DVertexShader9 *vs;
12712 D3DCOLOR color;
12714 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12715 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12716 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12718 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12719 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12720 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12721 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12723 hr = IDirect3DDevice9_BeginScene(device);
12724 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12726 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12727 hr = IDirect3DDevice9_EndScene(device);
12728 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12730 color = getPixelColor(device, 320, 240);
12731 ok(color_match(color, vs_body[i].r600, 1)
12732 || color_match(color, vs_body[i].nv40, 1)
12733 || color_match(color, vs_body[i].nv50, 1),
12734 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12735 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12737 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12738 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12740 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12741 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12742 IDirect3DVertexShader9_Release(vs);
12745 HeapFree(GetProcessHeap(), 0, vs_code);
12747 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12748 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12749 IDirect3DPixelShader9_Release(ps);
12752 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12754 IDirect3D9 *d3d;
12755 IDirect3DSurface9 *rt, *backbuffer;
12756 IDirect3DTexture9 *texture;
12757 HRESULT hr;
12758 int i;
12759 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12760 static const struct
12762 D3DFORMAT fmt;
12763 const char *name;
12765 formats[] =
12767 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12768 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12769 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12770 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12771 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12773 static const struct
12775 float x, y, z;
12776 float u, v;
12778 quad[] =
12780 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12781 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12782 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12783 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12786 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12787 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12789 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12790 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12791 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12792 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12793 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12795 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12797 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12799 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12800 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12802 skip("Format %s not supported as render target, skipping test.\n",
12803 formats[i].name);
12804 continue;
12807 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12808 D3DPOOL_DEFAULT, &texture, NULL);
12809 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12811 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12813 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12814 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12815 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12816 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12817 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12818 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12820 hr = IDirect3DDevice9_BeginScene(device);
12821 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12822 if(SUCCEEDED(hr))
12824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12825 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12826 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12827 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12829 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12832 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12833 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12834 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12835 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12836 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12837 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12838 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12840 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12841 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12842 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12844 hr = IDirect3DDevice9_EndScene(device);
12845 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12848 IDirect3DSurface9_Release(rt);
12849 IDirect3DTexture9_Release(texture);
12851 color = getPixelColor(device, 360, 240);
12852 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12853 D3DUSAGE_QUERY_SRGBWRITE,
12854 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12856 /* Big slop for R5G6B5 */
12857 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12858 formats[i].name, color_srgb, color);
12860 else
12862 /* Big slop for R5G6B5 */
12863 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12864 formats[i].name, color_rgb, color);
12867 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12868 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12871 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12872 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12874 IDirect3D9_Release(d3d);
12875 IDirect3DSurface9_Release(backbuffer);
12878 static void ds_size_test(IDirect3DDevice9 *device)
12880 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12881 HRESULT hr;
12882 DWORD num_passes;
12883 struct
12885 float x, y, z;
12887 quad[] =
12889 {-1.0, -1.0, 0.0 },
12890 {-1.0, 1.0, 0.0 },
12891 { 1.0, -1.0, 0.0 },
12892 { 1.0, 1.0, 0.0 }
12895 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12896 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12897 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12898 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12899 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12900 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12903 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12905 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12907 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12908 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12909 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12910 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12911 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12912 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12913 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12914 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12915 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12916 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12917 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12918 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12919 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12921 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12922 * but does not change the surface's contents. */
12923 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12924 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12926 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12928 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12930 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12932 /* Turning on any depth-related state results in a ValidateDevice failure */
12933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12934 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12935 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12936 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12937 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12939 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12941 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12942 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12943 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12944 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12946 /* Try to draw with the device in an invalid state */
12947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12948 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12949 hr = IDirect3DDevice9_BeginScene(device);
12950 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12951 if(SUCCEEDED(hr))
12953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12954 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12955 hr = IDirect3DDevice9_EndScene(device);
12956 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12958 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12959 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12960 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12963 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12964 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12965 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12966 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12967 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12968 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12970 IDirect3DSurface9_Release(readback);
12971 IDirect3DSurface9_Release(ds);
12972 IDirect3DSurface9_Release(rt);
12973 IDirect3DSurface9_Release(old_rt);
12974 IDirect3DSurface9_Release(old_ds);
12977 static void unbound_sampler_test(IDirect3DDevice9 *device)
12979 HRESULT hr;
12980 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12981 IDirect3DSurface9 *rt, *old_rt;
12982 DWORD color;
12983 D3DCAPS9 caps;
12985 static const DWORD ps_code[] =
12987 0xffff0200, /* ps_2_0 */
12988 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12989 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12990 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12991 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12992 0x0000ffff, /* end */
12994 static const DWORD ps_code_cube[] =
12996 0xffff0200, /* ps_2_0 */
12997 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
12998 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12999 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13000 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
13001 0x0000ffff, /* end */
13003 static const DWORD ps_code_volume[] =
13005 0xffff0200, /* ps_2_0 */
13006 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
13007 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13008 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13009 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
13010 0x0000ffff, /* end */
13013 static const struct
13015 float x, y, z;
13016 float u, v;
13018 quad[] =
13020 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
13021 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
13022 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
13023 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
13026 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13027 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13028 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
13030 skip("No cube / volume textures support, skipping the unbound sampler test.\n");
13031 return;
13034 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13035 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
13037 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13038 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
13039 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
13040 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
13041 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
13042 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
13044 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
13045 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
13047 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
13048 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
13050 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13051 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
13053 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
13054 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
13056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
13057 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
13059 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13060 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
13062 hr = IDirect3DDevice9_BeginScene(device);
13063 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
13064 if(SUCCEEDED(hr))
13066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13067 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
13069 hr = IDirect3DDevice9_EndScene(device);
13070 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
13073 color = getPixelColorFromSurface(rt, 32, 32);
13074 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
13076 /* Now try with a cube texture */
13077 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
13078 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
13080 hr = IDirect3DDevice9_BeginScene(device);
13081 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
13082 if (SUCCEEDED(hr))
13084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13085 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
13087 hr = IDirect3DDevice9_EndScene(device);
13088 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
13091 color = getPixelColorFromSurface(rt, 32, 32);
13092 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
13094 /* And then with a volume texture */
13095 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
13096 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
13098 hr = IDirect3DDevice9_BeginScene(device);
13099 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
13100 if (SUCCEEDED(hr))
13102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13103 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
13105 hr = IDirect3DDevice9_EndScene(device);
13106 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
13109 color = getPixelColorFromSurface(rt, 32, 32);
13110 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
13112 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
13113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
13115 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13116 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
13118 IDirect3DSurface9_Release(rt);
13119 IDirect3DSurface9_Release(old_rt);
13120 IDirect3DPixelShader9_Release(ps);
13121 IDirect3DPixelShader9_Release(ps_cube);
13122 IDirect3DPixelShader9_Release(ps_volume);
13125 static void update_surface_test(IDirect3DDevice9 *device)
13127 static const BYTE blocks[][8] =
13129 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
13130 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
13131 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
13132 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
13133 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
13134 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
13135 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
13137 static const struct
13139 UINT x, y;
13140 D3DCOLOR color;
13142 expected_colors[] =
13144 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
13145 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
13146 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
13147 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
13148 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13149 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13150 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
13152 static const struct
13154 float x, y, z, w;
13155 float u, v;
13157 tri[] =
13159 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
13160 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
13161 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
13163 static const RECT rect_2x2 = {0, 0, 2, 2};
13164 static const struct
13166 UINT src_level;
13167 UINT dst_level;
13168 const RECT *r;
13169 HRESULT hr;
13171 block_size_tests[] =
13173 {1, 0, NULL, D3D_OK},
13174 {0, 1, NULL, D3DERR_INVALIDCALL},
13175 {5, 4, NULL, D3DERR_INVALIDCALL},
13176 {4, 5, NULL, D3DERR_INVALIDCALL},
13177 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
13178 {5, 5, &rect_2x2, D3D_OK},
13181 IDirect3DSurface9 *src_surface, *dst_surface;
13182 IDirect3DTexture9 *src_tex, *dst_tex;
13183 IDirect3D9 *d3d;
13184 UINT count, i;
13185 HRESULT hr;
13187 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
13188 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
13190 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13191 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
13192 IDirect3D9_Release(d3d);
13193 if (FAILED(hr))
13195 skip("DXT1 not supported, skipping test.\n");
13196 return;
13199 IDirect3D9_Release(d3d);
13201 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
13202 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
13203 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
13204 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
13206 count = IDirect3DTexture9_GetLevelCount(src_tex);
13207 ok(count == 7, "Got level count %u, expected 7.\n", count);
13209 for (i = 0; i < count; ++i)
13211 UINT row_count, block_count, x, y;
13212 D3DSURFACE_DESC desc;
13213 BYTE *row, *block;
13214 D3DLOCKED_RECT r;
13216 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
13217 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
13219 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
13220 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
13222 row_count = ((desc.Height + 3) & ~3) / 4;
13223 block_count = ((desc.Width + 3) & ~3) / 4;
13224 row = r.pBits;
13226 for (y = 0; y < row_count; ++y)
13228 block = row;
13229 for (x = 0; x < block_count; ++x)
13231 memcpy(block, blocks[i], sizeof(blocks[i]));
13232 block += sizeof(blocks[i]);
13234 row += r.Pitch;
13237 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
13238 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
13241 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
13243 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
13244 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13245 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
13246 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13248 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
13249 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
13250 hr, i, block_size_tests[i].hr);
13252 IDirect3DSurface9_Release(dst_surface);
13253 IDirect3DSurface9_Release(src_surface);
13256 for (i = 0; i < count; ++i)
13258 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
13259 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13260 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
13261 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13263 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
13264 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
13266 IDirect3DSurface9_Release(dst_surface);
13267 IDirect3DSurface9_Release(src_surface);
13270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13271 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13272 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13273 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13274 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
13275 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13276 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
13277 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13278 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13279 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13280 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13281 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13283 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
13284 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13286 hr = IDirect3DDevice9_BeginScene(device);
13287 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
13289 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13290 hr = IDirect3DDevice9_EndScene(device);
13291 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13293 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13295 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13296 ok(color_match(color, expected_colors[i].color, 0),
13297 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13298 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13301 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13302 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13304 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13305 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13306 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13307 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13308 IDirect3DTexture9_Release(dst_tex);
13309 IDirect3DTexture9_Release(src_tex);
13312 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13314 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13315 IDirect3D9 *d3d9;
13316 HRESULT hr;
13318 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13319 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13320 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13321 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13322 IDirect3D9_Release(d3d9);
13323 if (FAILED(hr))
13325 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13326 return;
13329 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13330 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13331 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13332 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13333 D3DPOOL_SYSTEMMEM, &readback, NULL);
13334 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13336 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13337 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13338 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13339 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13341 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13342 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13343 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13344 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13346 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13347 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13348 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13349 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13351 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13352 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13353 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13354 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13356 IDirect3DSurface9_Release(original_ds);
13357 IDirect3DSurface9_Release(original_rt);
13358 IDirect3DSurface9_Release(readback);
13359 IDirect3DSurface9_Release(rt);
13362 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13364 IDirect3DDevice9 *device = 0;
13365 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13366 D3DCAPS9 caps;
13367 HRESULT hr;
13368 D3DPRESENT_PARAMETERS present_parameters;
13369 unsigned int i;
13370 static const struct
13372 float x, y, z;
13373 D3DCOLOR color;
13375 quad_1[] =
13377 { -1.0f, 1.0f, 0.0f, 0xffff0000},
13378 { 1.0f, 1.0f, 1.0f, 0xffff0000},
13379 { -1.0f, -1.0f, 0.0f, 0xffff0000},
13380 { 1.0f, -1.0f, 1.0f, 0xffff0000},
13382 quad_2[] =
13384 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
13385 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
13386 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13387 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
13389 static const struct
13391 UINT x, y;
13392 D3DCOLOR color;
13394 expected_colors[] =
13396 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13397 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13398 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13399 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13400 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13401 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13402 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13403 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13406 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13407 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13408 if (FAILED(hr))
13410 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13411 return;
13413 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13414 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13415 if (FAILED(hr))
13417 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13418 return;
13421 ZeroMemory(&present_parameters, sizeof(present_parameters));
13422 present_parameters.Windowed = TRUE;
13423 present_parameters.hDeviceWindow = create_window();
13424 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13425 present_parameters.BackBufferWidth = 640;
13426 present_parameters.BackBufferHeight = 480;
13427 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13428 present_parameters.EnableAutoDepthStencil = TRUE;
13429 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13430 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13432 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13433 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13434 &present_parameters, &device);
13435 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13437 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13438 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13439 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13441 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13442 goto cleanup;
13445 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13446 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13447 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13448 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13449 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13450 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13452 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13453 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13454 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13455 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13458 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13460 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13462 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13464 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13465 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13466 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13468 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13469 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13471 /* Render onscreen and then offscreen */
13472 hr = IDirect3DDevice9_BeginScene(device);
13473 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13475 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13476 hr = IDirect3DDevice9_EndScene(device);
13477 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13479 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13480 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13481 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13482 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13484 hr = IDirect3DDevice9_BeginScene(device);
13485 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13487 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13488 hr = IDirect3DDevice9_EndScene(device);
13489 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13491 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13492 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13494 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13496 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13497 ok(color_match(color, expected_colors[i].color, 1),
13498 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13499 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13502 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13503 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13504 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13505 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13507 /* Render offscreen and then onscreen */
13508 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13509 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13510 IDirect3DSurface9_Release(ds);
13511 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13512 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13513 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13514 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13516 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13517 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13519 hr = IDirect3DDevice9_BeginScene(device);
13520 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13522 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13523 hr = IDirect3DDevice9_EndScene(device);
13524 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13526 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13527 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13528 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13529 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13531 hr = IDirect3DDevice9_BeginScene(device);
13532 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13534 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13535 hr = IDirect3DDevice9_EndScene(device);
13536 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13539 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13541 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13543 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13544 ok(color_match(color, expected_colors[i].color, 1),
13545 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13546 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13549 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13550 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13552 IDirect3DSurface9_Release(ds);
13553 IDirect3DSurface9_Release(readback);
13554 IDirect3DSurface9_Release(rt);
13555 IDirect3DSurface9_Release(original_rt);
13556 cleanup_device(device);
13558 ZeroMemory(&present_parameters, sizeof(present_parameters));
13559 present_parameters.Windowed = TRUE;
13560 present_parameters.hDeviceWindow = create_window();
13561 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13562 present_parameters.BackBufferWidth = 640;
13563 present_parameters.BackBufferHeight = 480;
13564 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13565 present_parameters.EnableAutoDepthStencil = TRUE;
13566 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13567 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13569 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13570 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13571 &present_parameters, &device);
13572 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13574 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13575 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13577 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13578 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13579 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13580 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13581 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13582 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13583 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13584 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13585 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13587 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13588 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13589 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13590 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13591 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13592 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13593 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13594 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13596 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13597 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13598 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13599 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13601 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13603 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13604 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13605 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13607 /* Render to a multisampled offscreen frame buffer and then blit to
13608 * the onscreen (not multisampled) frame buffer. */
13609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13610 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13612 hr = IDirect3DDevice9_BeginScene(device);
13613 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13614 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13615 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13616 hr = IDirect3DDevice9_EndScene(device);
13617 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13619 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13620 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13621 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13622 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13624 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13625 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13626 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13627 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13629 hr = IDirect3DDevice9_BeginScene(device);
13630 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13632 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13633 hr = IDirect3DDevice9_EndScene(device);
13634 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13636 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13637 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13639 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13641 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13642 ok(color_match(color, expected_colors[i].color, 1),
13643 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13644 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13648 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13650 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13651 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13652 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13653 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13655 IDirect3DSurface9_Release(original_ds);
13656 IDirect3DSurface9_Release(original_rt);
13657 IDirect3DSurface9_Release(ds);
13658 IDirect3DSurface9_Release(readback);
13659 IDirect3DSurface9_Release(rt);
13660 cleanup:
13661 cleanup_device(device);
13664 static void resz_test(IDirect3D9 *d3d9)
13666 IDirect3DDevice9 *device = 0;
13667 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13668 D3DCAPS9 caps;
13669 HRESULT hr;
13670 D3DPRESENT_PARAMETERS present_parameters;
13671 unsigned int i;
13672 static const DWORD ps_code[] =
13674 0xffff0200, /* ps_2_0 */
13675 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13676 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13677 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13678 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13679 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13680 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13681 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13682 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13683 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13684 0x0000ffff, /* end */
13686 struct
13688 float x, y, z;
13689 float s, t, p, q;
13691 quad[] =
13693 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13694 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13695 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13696 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13698 struct
13700 UINT x, y;
13701 D3DCOLOR color;
13703 expected_colors[] =
13705 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13706 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13707 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13708 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13709 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13710 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13711 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13712 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13714 IDirect3DTexture9 *texture;
13715 IDirect3DPixelShader9 *ps;
13716 DWORD value;
13718 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13719 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13720 if (FAILED(hr))
13722 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13723 return;
13725 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13726 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13727 if (FAILED(hr))
13729 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13730 return;
13733 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13734 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13735 if (FAILED(hr))
13737 skip("No INTZ support, skipping RESZ test.\n");
13738 return;
13741 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13742 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13743 if (FAILED(hr))
13745 skip("No RESZ support, skipping RESZ test.\n");
13746 return;
13749 ZeroMemory(&present_parameters, sizeof(present_parameters));
13750 present_parameters.Windowed = TRUE;
13751 present_parameters.hDeviceWindow = create_window();
13752 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13753 present_parameters.BackBufferWidth = 640;
13754 present_parameters.BackBufferHeight = 480;
13755 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13756 present_parameters.EnableAutoDepthStencil = FALSE;
13757 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13758 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13760 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13761 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13762 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13764 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13765 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13766 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13768 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13769 cleanup_device(device);
13770 return;
13772 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13774 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13775 cleanup_device(device);
13776 return;
13779 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13780 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13782 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13783 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13784 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13785 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13786 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13787 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13788 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13789 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13791 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13792 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13793 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13794 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13795 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13796 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13797 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13798 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13799 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13800 IDirect3DSurface9_Release(intz_ds);
13801 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13802 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13804 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13805 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13807 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13809 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13811 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13815 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13816 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13817 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13818 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13819 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13820 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13822 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13823 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13824 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13826 /* Render offscreen (multisampled), blit the depth buffer
13827 * into the INTZ texture and then check its contents */
13828 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13829 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13830 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13831 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13832 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13833 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13835 hr = IDirect3DDevice9_BeginScene(device);
13836 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13837 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13838 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13840 /* The destination depth texture has to be bound to sampler 0 */
13841 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13842 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13844 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13846 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13848 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13850 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13852 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13854 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13856 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13858 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13860 /* The actual multisampled depth buffer resolve happens here */
13861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13862 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13863 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13864 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13866 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13867 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13868 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13869 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13871 /* Read the depth values back */
13872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13873 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13874 hr = IDirect3DDevice9_EndScene(device);
13875 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13877 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13879 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13880 ok(color_match(color, expected_colors[i].color, 1),
13881 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13882 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13885 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13886 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13888 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13889 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13890 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13891 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13892 IDirect3DSurface9_Release(ds);
13893 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13894 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13895 IDirect3DTexture9_Release(texture);
13896 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13897 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13898 IDirect3DPixelShader9_Release(ps);
13899 IDirect3DSurface9_Release(readback);
13900 IDirect3DSurface9_Release(original_rt);
13901 IDirect3DSurface9_Release(rt);
13902 cleanup_device(device);
13905 ZeroMemory(&present_parameters, sizeof(present_parameters));
13906 present_parameters.Windowed = TRUE;
13907 present_parameters.hDeviceWindow = create_window();
13908 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13909 present_parameters.BackBufferWidth = 640;
13910 present_parameters.BackBufferHeight = 480;
13911 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13912 present_parameters.EnableAutoDepthStencil = TRUE;
13913 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13914 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13916 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13917 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13918 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13920 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13921 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13922 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13923 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13924 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13925 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13926 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13927 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13928 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13929 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13930 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13931 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13932 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13933 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13934 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13935 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13937 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13938 IDirect3DSurface9_Release(intz_ds);
13939 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13940 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13942 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13943 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13945 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13947 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13949 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13951 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13953 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13954 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13955 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13956 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13957 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13958 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13959 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13960 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13961 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13962 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13964 /* Render onscreen, blit the depth buffer into the INTZ texture
13965 * and then check its contents */
13966 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13967 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13968 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13969 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13971 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13973 hr = IDirect3DDevice9_BeginScene(device);
13974 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13976 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13977 hr = IDirect3DDevice9_EndScene(device);
13978 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13980 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13981 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13983 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13984 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13986 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13988 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13990 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13992 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13994 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13996 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13998 /* The actual multisampled depth buffer resolve happens here */
13999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
14000 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
14001 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
14002 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
14004 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
14005 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14006 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14007 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14009 /* Read the depth values back */
14010 hr = IDirect3DDevice9_BeginScene(device);
14011 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14012 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14013 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14014 hr = IDirect3DDevice9_EndScene(device);
14015 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14017 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14019 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14020 ok(color_match(color, expected_colors[i].color, 1),
14021 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14022 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14025 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14026 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14029 /* Test edge cases - try with no texture at all */
14030 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14031 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14032 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14033 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14035 hr = IDirect3DDevice9_BeginScene(device);
14036 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14039 hr = IDirect3DDevice9_EndScene(device);
14040 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
14043 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
14045 /* With a non-multisampled depth buffer */
14046 IDirect3DSurface9_Release(ds);
14047 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14048 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
14050 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
14051 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14052 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14053 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14054 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14055 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14057 hr = IDirect3DDevice9_BeginScene(device);
14058 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14059 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14060 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14062 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14063 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14066 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14068 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
14070 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14072 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
14074 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14076 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
14078 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14079 hr = IDirect3DDevice9_EndScene(device);
14080 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
14083 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
14085 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14086 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14088 /* Read the depth values back. */
14089 hr = IDirect3DDevice9_BeginScene(device);
14090 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14092 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14093 hr = IDirect3DDevice9_EndScene(device);
14094 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14096 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14098 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14099 ok(color_match(color, expected_colors[i].color, 1),
14100 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14101 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14104 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14105 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14107 /* Without a current depth-stencil buffer set */
14108 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14109 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14110 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14111 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14113 hr = IDirect3DDevice9_BeginScene(device);
14114 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14115 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14116 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14117 hr = IDirect3DDevice9_EndScene(device);
14118 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
14121 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
14123 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14124 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14125 IDirect3DSurface9_Release(ds);
14126 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14127 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14128 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14129 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14130 IDirect3DTexture9_Release(texture);
14131 IDirect3DPixelShader9_Release(ps);
14132 IDirect3DSurface9_Release(readback);
14133 IDirect3DSurface9_Release(original_rt);
14134 cleanup_device(device);
14137 static void zenable_test(IDirect3DDevice9 *device)
14139 static const struct
14141 struct vec4 position;
14142 D3DCOLOR diffuse;
14144 tquad[] =
14146 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
14147 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
14148 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
14149 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
14151 D3DCOLOR color;
14152 D3DCAPS9 caps;
14153 HRESULT hr;
14154 UINT x, y;
14155 UINT i, j;
14157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14158 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
14159 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
14160 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
14162 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
14163 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14164 hr = IDirect3DDevice9_BeginScene(device);
14165 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
14167 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14168 hr = IDirect3DDevice9_EndScene(device);
14169 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14171 for (i = 0; i < 4; ++i)
14173 for (j = 0; j < 4; ++j)
14175 x = 80 * ((2 * j) + 1);
14176 y = 60 * ((2 * i) + 1);
14177 color = getPixelColor(device, x, y);
14178 ok(color_match(color, 0x0000ff00, 1),
14179 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
14183 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14184 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
14186 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14187 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14189 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
14190 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14192 static const DWORD vs_code[] =
14194 0xfffe0101, /* vs_1_1 */
14195 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14196 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14197 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
14198 0x0000ffff
14200 static const DWORD ps_code[] =
14202 0xffff0101, /* ps_1_1 */
14203 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
14204 0x0000ffff /* end */
14206 static const struct vec3 quad[] =
14208 {-1.0f, -1.0f, -0.5f},
14209 {-1.0f, 1.0f, -0.5f},
14210 { 1.0f, -1.0f, 1.5f},
14211 { 1.0f, 1.0f, 1.5f},
14213 static const D3DCOLOR expected[] =
14215 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
14216 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
14217 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
14218 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
14221 IDirect3DVertexShader9 *vs;
14222 IDirect3DPixelShader9 *ps;
14224 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14225 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
14226 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
14227 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
14228 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14229 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
14230 hr = IDirect3DDevice9_SetVertexShader(device, vs);
14231 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14232 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14233 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14235 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
14236 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14237 hr = IDirect3DDevice9_BeginScene(device);
14238 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14240 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14241 hr = IDirect3DDevice9_EndScene(device);
14242 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14244 for (i = 0; i < 4; ++i)
14246 for (j = 0; j < 4; ++j)
14248 x = 80 * ((2 * j) + 1);
14249 y = 60 * ((2 * i) + 1);
14250 color = getPixelColor(device, x, y);
14251 ok(color_match(color, expected[i * 4 + j], 1),
14252 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
14256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14257 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
14259 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14260 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14261 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14262 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14263 IDirect3DPixelShader9_Release(ps);
14264 IDirect3DVertexShader9_Release(vs);
14268 static void fog_special_test(IDirect3DDevice9 *device)
14270 static const struct
14272 struct vec3 position;
14273 D3DCOLOR diffuse;
14275 quad[] =
14277 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
14278 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
14279 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
14280 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
14282 static const struct
14284 DWORD vertexmode, tablemode;
14285 BOOL vs, ps;
14286 D3DCOLOR color_left, color_right;
14288 tests[] =
14290 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
14291 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
14292 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
14293 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
14295 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
14296 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
14297 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
14298 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
14300 static const DWORD pixel_shader_code[] =
14302 0xffff0101, /* ps_1_1 */
14303 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
14304 0x0000ffff
14306 static const DWORD vertex_shader_code[] =
14308 0xfffe0101, /* vs_1_1 */
14309 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14310 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14311 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14312 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14313 0x0000ffff
14315 union
14317 float f;
14318 DWORD d;
14319 } conv;
14320 DWORD color;
14321 HRESULT hr;
14322 unsigned int i;
14323 IDirect3DPixelShader9 *ps;
14324 IDirect3DVertexShader9 *vs;
14325 D3DCAPS9 caps;
14327 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14328 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14329 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14331 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
14332 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
14334 else
14336 skip("Vertex Shaders not supported, skipping some fog tests.\n");
14337 vs = NULL;
14339 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14341 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
14342 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
14344 else
14346 skip("Pixel Shaders not supported, skipping some fog tests.\n");
14347 ps = NULL;
14350 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14351 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
14352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
14353 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
14354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
14355 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
14357 conv.f = 0.5f;
14358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
14359 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
14360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
14361 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
14363 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
14365 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
14366 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14368 if (!tests[i].vs)
14370 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14371 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14373 else if (vs)
14375 hr = IDirect3DDevice9_SetVertexShader(device, vs);
14376 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14378 else
14380 continue;
14383 if (!tests[i].ps)
14385 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14386 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14388 else if (ps)
14390 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14391 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14393 else
14395 continue;
14398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
14399 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
14400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
14401 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
14403 hr = IDirect3DDevice9_BeginScene(device);
14404 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14407 hr = IDirect3DDevice9_EndScene(device);
14408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14410 color = getPixelColor(device, 310, 240);
14411 ok(color_match(color, tests[i].color_left, 1),
14412 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
14413 color = getPixelColor(device, 330, 240);
14414 ok(color_match(color, tests[i].color_right, 1),
14415 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
14417 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14418 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
14421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
14422 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
14423 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14424 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14425 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14426 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14427 if (vs)
14428 IDirect3DVertexShader9_Release(vs);
14429 if (ps)
14430 IDirect3DPixelShader9_Release(ps);
14433 START_TEST(visual)
14435 IDirect3D9 *d3d9;
14436 IDirect3DDevice9 *device_ptr;
14437 D3DCAPS9 caps;
14438 HRESULT hr;
14439 DWORD color;
14441 d3d9_handle = LoadLibraryA("d3d9.dll");
14442 if (!d3d9_handle)
14444 skip("Could not load d3d9.dll\n");
14445 return;
14448 device_ptr = init_d3d9();
14449 if (!device_ptr)
14451 skip("Creating the device failed\n");
14452 return;
14455 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14457 /* Check for the reliability of the returned data */
14458 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14459 if(FAILED(hr))
14461 skip("Clear failed, can't assure correctness of the test results, skipping\n");
14462 goto cleanup;
14465 color = getPixelColor(device_ptr, 1, 1);
14466 if(color !=0x00ff0000)
14468 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14469 goto cleanup;
14471 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14473 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14474 if(FAILED(hr))
14476 skip("Clear failed, can't assure correctness of the test results, skipping\n");
14477 goto cleanup;
14480 color = getPixelColor(device_ptr, 639, 479);
14481 if(color != 0x0000ddee)
14483 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14484 goto cleanup;
14486 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14488 /* Now execute the real tests */
14489 depth_clamp_test(device_ptr);
14490 stretchrect_test(device_ptr);
14491 lighting_test(device_ptr);
14492 clear_test(device_ptr);
14493 color_fill_test(device_ptr);
14494 fog_test(device_ptr);
14495 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14497 test_cube_wrap(device_ptr);
14498 } else {
14499 skip("No cube texture support\n");
14501 z_range_test(device_ptr);
14502 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14504 maxmip_test(device_ptr);
14506 else
14508 skip("No mipmap support\n");
14510 offscreen_test(device_ptr);
14511 ds_size_test(device_ptr);
14512 alpha_test(device_ptr);
14513 shademode_test(device_ptr);
14514 srgbtexture_test(device_ptr);
14515 release_buffer_test(device_ptr);
14516 float_texture_test(device_ptr);
14517 g16r16_texture_test(device_ptr);
14518 pixelshader_blending_test(device_ptr);
14519 texture_transform_flags_test(device_ptr);
14520 autogen_mipmap_test(device_ptr);
14521 fixed_function_decl_test(device_ptr);
14522 conditional_np2_repeat_test(device_ptr);
14523 fixed_function_bumpmap_test(device_ptr);
14524 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14525 stencil_cull_test(device_ptr);
14526 } else {
14527 skip("No two sided stencil support\n");
14529 pointsize_test(device_ptr);
14530 tssargtemp_test(device_ptr);
14531 np2_stretch_rect_test(device_ptr);
14532 yuv_color_test(device_ptr);
14533 zwriteenable_test(device_ptr);
14534 alphatest_test(device_ptr);
14535 viewport_test(device_ptr);
14537 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14539 test_constant_clamp_vs(device_ptr);
14540 test_compare_instructions(device_ptr);
14542 else skip("No vs_1_1 support\n");
14544 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14546 test_mova(device_ptr);
14547 loop_index_test(device_ptr);
14548 sincos_test(device_ptr);
14549 sgn_test(device_ptr);
14550 clip_planes_test(device_ptr);
14551 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14552 test_vshader_input(device_ptr);
14553 test_vshader_float16(device_ptr);
14554 stream_test(device_ptr);
14555 } else {
14556 skip("No vs_3_0 support\n");
14559 else skip("No vs_2_0 support\n");
14561 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14563 fog_with_shader_test(device_ptr);
14565 else skip("No vs_2_0 and ps_2_0 support\n");
14567 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14569 texbem_test(device_ptr);
14570 texdepth_test(device_ptr);
14571 texkill_test(device_ptr);
14572 x8l8v8u8_test(device_ptr);
14573 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14574 constant_clamp_ps_test(device_ptr);
14575 cnd_test(device_ptr);
14576 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14577 dp2add_ps_test(device_ptr);
14578 unbound_sampler_test(device_ptr);
14579 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14580 nested_loop_test(device_ptr);
14581 pretransformed_varying_test(device_ptr);
14582 vFace_register_test(device_ptr);
14583 vpos_register_test(device_ptr);
14584 multiple_rendertargets_test(device_ptr);
14585 } else {
14586 skip("No ps_3_0 or vs_3_0 support\n");
14588 } else {
14589 skip("No ps_2_0 support\n");
14593 else skip("No ps_1_1 support\n");
14595 texop_test(device_ptr);
14596 texop_range_test(device_ptr);
14597 alphareplicate_test(device_ptr);
14598 dp3_alpha_test(device_ptr);
14599 depth_buffer_test(device_ptr);
14600 depth_buffer2_test(device_ptr);
14601 depth_blit_test(device_ptr);
14602 intz_test(device_ptr);
14603 shadow_test(device_ptr);
14604 fp_special_test(device_ptr);
14605 depth_bounds_test(device_ptr);
14606 srgbwrite_format_test(device_ptr);
14607 update_surface_test(device_ptr);
14608 multisample_get_rtdata_test(device_ptr);
14609 zenable_test(device_ptr);
14610 fog_special_test(device_ptr);
14612 hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14613 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14614 cleanup_device(device_ptr);
14615 device_ptr = NULL;
14617 multisampled_depth_buffer_test(d3d9);
14618 resz_test(d3d9);
14620 IDirect3D9_Release(d3d9);
14622 cleanup:
14623 cleanup_device(device_ptr);