d3d9/tests: Add a multisampled -> not multisampled depth buffer blit test.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
bloba69747f26bf7bedcf8d7aa98b2c0420cf4f734a2
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
114 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115 if (FAILED(hr) || !surf)
117 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118 return 0xdeadbeef;
121 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122 if(FAILED(hr))
124 trace("Can't get the render target, hr=%08x\n", hr);
125 ret = 0xdeadbeed;
126 goto out;
129 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130 if (FAILED(hr))
132 trace("Can't read the render target data, hr=%08x\n", hr);
133 ret = 0xdeadbeec;
134 goto out;
137 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138 if(FAILED(hr))
140 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141 ret = 0xdeadbeeb;
142 goto out;
145 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146 * really important for these tests
148 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149 hr = IDirect3DSurface9_UnlockRect(surf);
150 if(FAILED(hr))
152 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
155 out:
156 if(target) IDirect3DSurface9_Release(target);
157 if(surf) IDirect3DSurface9_Release(surf);
158 return ret;
161 static IDirect3DDevice9 *init_d3d9(void)
163 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164 IDirect3D9 *d3d9_ptr = 0;
165 IDirect3DDevice9 *device_ptr = 0;
166 D3DPRESENT_PARAMETERS present_parameters;
167 HRESULT hr;
168 D3DADAPTER_IDENTIFIER9 identifier;
170 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172 if (!d3d9_create) return NULL;
174 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175 if (!d3d9_ptr)
177 win_skip("could not create D3D9\n");
178 return NULL;
181 ZeroMemory(&present_parameters, sizeof(present_parameters));
182 present_parameters.Windowed = TRUE;
183 present_parameters.hDeviceWindow = create_window();
184 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185 present_parameters.BackBufferWidth = 640;
186 present_parameters.BackBufferHeight = 480;
187 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188 present_parameters.EnableAutoDepthStencil = TRUE;
189 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
191 memset(&identifier, 0, sizeof(identifier));
192 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194 trace("Driver string: \"%s\"\n", identifier.Driver);
195 trace("Description string: \"%s\"\n", identifier.Description);
196 ok(identifier.Description[0] != '\0', "Empty driver description\n");
197 trace("Device name string: \"%s\"\n", identifier.DeviceName);
198 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
199 trace("Driver version %d.%d.%d.%d\n",
200 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
203 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
204 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
205 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
206 "Failed to create a device, hr %#x.\n", hr);
208 return device_ptr;
211 static void cleanup_device(IDirect3DDevice9 *device)
213 if (device)
215 D3DPRESENT_PARAMETERS present_parameters;
216 IDirect3DSwapChain9 *swapchain;
217 ULONG ref;
219 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
220 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
221 IDirect3DSwapChain9_Release(swapchain);
222 ref = IDirect3DDevice9_Release(device);
223 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
224 DestroyWindow(present_parameters.hDeviceWindow);
228 struct vertex
230 float x, y, z;
231 DWORD diffuse;
234 struct tvertex
236 float x, y, z, rhw;
237 DWORD diffuse;
240 struct nvertex
242 float x, y, z;
243 float nx, ny, nz;
244 DWORD diffuse;
247 static void lighting_test(IDirect3DDevice9 *device)
249 HRESULT hr;
250 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
251 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
252 DWORD color;
253 D3DMATERIAL9 material, old_material;
254 DWORD cop, carg;
255 DWORD old_colorwrite;
257 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
258 0.0f, 1.0f, 0.0f, 0.0f,
259 0.0f, 0.0f, 1.0f, 0.0f,
260 0.0f, 0.0f, 0.0f, 1.0f };
262 struct vertex unlitquad[] =
264 {-1.0f, -1.0f, 0.1f, 0xffff0000},
265 {-1.0f, 0.0f, 0.1f, 0xffff0000},
266 { 0.0f, 0.0f, 0.1f, 0xffff0000},
267 { 0.0f, -1.0f, 0.1f, 0xffff0000},
269 struct vertex litquad[] =
271 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
272 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
273 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
274 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
276 struct nvertex unlitnquad[] =
278 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
279 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
280 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
281 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
283 struct nvertex litnquad[] =
285 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
286 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
287 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
288 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
290 WORD Indices[] = {0, 1, 2, 2, 3, 0};
292 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
293 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
295 /* Setup some states that may cause issues */
296 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
297 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
298 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
299 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
300 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
301 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
318 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
319 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
323 hr = IDirect3DDevice9_SetFVF(device, 0);
324 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
326 hr = IDirect3DDevice9_SetFVF(device, fvf);
327 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
329 hr = IDirect3DDevice9_BeginScene(device);
330 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
331 if(hr == D3D_OK)
333 /* No lights are defined... That means, lit vertices should be entirely black */
334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
336 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
337 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
338 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
342 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
343 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
344 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
346 hr = IDirect3DDevice9_SetFVF(device, nfvf);
347 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
350 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
351 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
352 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
353 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
355 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
356 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
357 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
358 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
359 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
361 IDirect3DDevice9_EndScene(device);
362 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
365 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
366 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
367 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
368 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
369 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
370 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
371 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
372 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
374 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
376 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
377 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
378 memset(&material, 0, sizeof(material));
379 material.Diffuse.r = 0.0;
380 material.Diffuse.g = 0.0;
381 material.Diffuse.b = 0.0;
382 material.Diffuse.a = 1.0;
383 material.Ambient.r = 0.0;
384 material.Ambient.g = 0.0;
385 material.Ambient.b = 0.0;
386 material.Ambient.a = 0.0;
387 material.Specular.r = 0.0;
388 material.Specular.g = 0.0;
389 material.Specular.b = 0.0;
390 material.Specular.a = 0.0;
391 material.Emissive.r = 0.0;
392 material.Emissive.g = 0.0;
393 material.Emissive.b = 0.0;
394 material.Emissive.a = 0.0;
395 material.Power = 0.0;
396 IDirect3DDevice9_SetMaterial(device, &material);
397 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
400 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
404 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
405 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
406 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
407 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
408 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
410 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
411 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
413 hr = IDirect3DDevice9_BeginScene(device);
414 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
415 if(SUCCEEDED(hr)) {
416 struct vertex lighting_test[] = {
417 {-1.0, -1.0, 0.1, 0x8000ff00},
418 { 1.0, -1.0, 0.1, 0x80000000},
419 {-1.0, 1.0, 0.1, 0x8000ff00},
420 { 1.0, 1.0, 0.1, 0x80000000}
422 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
423 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
425 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
427 hr = IDirect3DDevice9_EndScene(device);
428 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
431 color = getPixelColor(device, 320, 240);
432 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
433 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
435 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
436 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
438 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
440 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
444 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
445 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
446 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
451 static void clear_test(IDirect3DDevice9 *device)
453 /* Tests the correctness of clearing parameters */
454 HRESULT hr;
455 D3DRECT rect[2];
456 D3DRECT rect_negneg;
457 DWORD color;
458 D3DVIEWPORT9 old_vp, vp;
459 RECT scissor;
460 DWORD oldColorWrite;
461 BOOL invalid_clear_failed = FALSE;
463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
464 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
466 /* Positive x, negative y */
467 rect[0].x1 = 0;
468 rect[0].y1 = 480;
469 rect[0].x2 = 320;
470 rect[0].y2 = 240;
472 /* Positive x, positive y */
473 rect[1].x1 = 0;
474 rect[1].y1 = 0;
475 rect[1].x2 = 320;
476 rect[1].y2 = 240;
477 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
478 * returns D3D_OK, but ignores the rectangle silently
480 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
481 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
482 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
484 /* negative x, negative y */
485 rect_negneg.x1 = 640;
486 rect_negneg.y1 = 240;
487 rect_negneg.x2 = 320;
488 rect_negneg.y2 = 0;
489 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
490 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
491 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
493 color = getPixelColor(device, 160, 360); /* lower left quad */
494 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
495 color = getPixelColor(device, 160, 120); /* upper left quad */
496 if(invalid_clear_failed) {
497 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
498 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
499 } else {
500 /* If the negative rectangle was dropped silently, the correct ones are cleared */
501 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
503 color = getPixelColor(device, 480, 360); /* lower right quad */
504 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
505 color = getPixelColor(device, 480, 120); /* upper right quad */
506 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
508 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
510 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
511 * clear the red quad in the top left part of the render target. For some reason it
512 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
513 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
514 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
515 * pick some obvious value
517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
518 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
520 /* Test how the viewport affects clears */
521 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
522 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
524 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
526 vp.X = 160;
527 vp.Y = 120;
528 vp.Width = 160;
529 vp.Height = 120;
530 vp.MinZ = 0.0;
531 vp.MaxZ = 1.0;
532 hr = IDirect3DDevice9_SetViewport(device, &vp);
533 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
535 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
537 vp.X = 320;
538 vp.Y = 240;
539 vp.Width = 320;
540 vp.Height = 240;
541 vp.MinZ = 0.0;
542 vp.MaxZ = 1.0;
543 hr = IDirect3DDevice9_SetViewport(device, &vp);
544 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
545 rect[0].x1 = 160;
546 rect[0].y1 = 120;
547 rect[0].x2 = 480;
548 rect[0].y2 = 360;
549 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
550 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
552 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
553 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555 color = getPixelColor(device, 158, 118);
556 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
557 color = getPixelColor(device, 162, 118);
558 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
559 color = getPixelColor(device, 158, 122);
560 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
561 color = getPixelColor(device, 162, 122);
562 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
564 color = getPixelColor(device, 318, 238);
565 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
566 color = getPixelColor(device, 322, 238);
567 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
568 color = getPixelColor(device, 318, 242);
569 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
570 color = getPixelColor(device, 322, 242);
571 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
573 color = getPixelColor(device, 478, 358);
574 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
575 color = getPixelColor(device, 482, 358);
576 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
577 color = getPixelColor(device, 478, 362);
578 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
579 color = getPixelColor(device, 482, 362);
580 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
582 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
584 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
585 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
587 scissor.left = 160;
588 scissor.right = 480;
589 scissor.top = 120;
590 scissor.bottom = 360;
591 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
592 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
594 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
596 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
597 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
598 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
599 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
601 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
602 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
604 color = getPixelColor(device, 158, 118);
605 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
606 color = getPixelColor(device, 162, 118);
607 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
608 color = getPixelColor(device, 158, 122);
609 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
610 color = getPixelColor(device, 162, 122);
611 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
613 color = getPixelColor(device, 158, 358);
614 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
615 color = getPixelColor(device, 162, 358);
616 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
617 color = getPixelColor(device, 158, 358);
618 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
619 color = getPixelColor(device, 162, 362);
620 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
622 color = getPixelColor(device, 478, 118);
623 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
624 color = getPixelColor(device, 478, 122);
625 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
626 color = getPixelColor(device, 482, 122);
627 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
628 color = getPixelColor(device, 482, 358);
629 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
631 color = getPixelColor(device, 478, 358);
632 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
633 color = getPixelColor(device, 478, 362);
634 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
635 color = getPixelColor(device, 482, 358);
636 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
637 color = getPixelColor(device, 482, 362);
638 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
640 color = getPixelColor(device, 318, 238);
641 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
642 color = getPixelColor(device, 318, 242);
643 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
644 color = getPixelColor(device, 322, 238);
645 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
646 color = getPixelColor(device, 322, 242);
647 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
649 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
651 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
652 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
654 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
656 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
657 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
658 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
660 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
661 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
666 /* Colorwriteenable does not affect the clear */
667 color = getPixelColor(device, 320, 240);
668 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
670 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
673 static void color_fill_test(IDirect3DDevice9 *device)
675 HRESULT hr;
676 IDirect3DSurface9 *backbuffer = NULL;
677 IDirect3DSurface9 *rt_surface = NULL;
678 IDirect3DSurface9 *offscreen_surface = NULL;
679 DWORD fill_color, color;
681 /* Test ColorFill on a the backbuffer (should pass) */
682 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
683 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
684 if(backbuffer)
686 fill_color = 0x112233;
687 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
688 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
690 color = getPixelColor(device, 0, 0);
691 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
693 IDirect3DSurface9_Release(backbuffer);
696 /* Test ColorFill on a render target surface (should pass) */
697 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
698 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
699 if(rt_surface)
701 fill_color = 0x445566;
702 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
703 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
705 color = getPixelColorFromSurface(rt_surface, 0, 0);
706 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
708 IDirect3DSurface9_Release(rt_surface);
711 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
712 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
714 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715 if(offscreen_surface)
717 fill_color = 0x778899;
718 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
719 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
721 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
722 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
724 IDirect3DSurface9_Release(offscreen_surface);
727 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
728 offscreen_surface = NULL;
729 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
730 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
731 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
732 if(offscreen_surface)
734 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
735 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
737 IDirect3DSurface9_Release(offscreen_surface);
741 typedef struct {
742 float in[4];
743 DWORD out;
744 } test_data_t;
747 * c7 mova ARGB mov ARGB
748 * -2.4 -2 0x00ffff00 -3 0x00ff0000
749 * -1.6 -2 0x00ffff00 -2 0x00ffff00
750 * -0.4 0 0x0000ffff -1 0x0000ff00
751 * 0.4 0 0x0000ffff 0 0x0000ffff
752 * 1.6 2 0x00ff00ff 1 0x000000ff
753 * 2.4 2 0x00ff00ff 2 0x00ff00ff
755 static void test_mova(IDirect3DDevice9 *device)
757 static const DWORD mova_test[] = {
758 0xfffe0200, /* vs_2_0 */
759 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
760 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
761 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
762 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
763 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
764 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
765 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
766 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
767 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
768 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
769 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
770 0x0000ffff /* END */
772 static const DWORD mov_test[] = {
773 0xfffe0101, /* vs_1_1 */
774 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
775 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
776 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
777 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
778 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
779 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
780 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
781 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
782 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
783 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
784 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
785 0x0000ffff /* END */
788 static const test_data_t test_data[2][6] = {
790 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
791 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
792 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
793 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
794 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
795 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
798 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
799 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
800 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
801 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
802 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
803 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
807 static const float quad[][3] = {
808 {-1.0f, -1.0f, 0.0f},
809 {-1.0f, 1.0f, 0.0f},
810 { 1.0f, -1.0f, 0.0f},
811 { 1.0f, 1.0f, 0.0f},
814 static const D3DVERTEXELEMENT9 decl_elements[] = {
815 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
816 D3DDECL_END()
819 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
820 IDirect3DVertexShader9 *mova_shader = NULL;
821 IDirect3DVertexShader9 *mov_shader = NULL;
822 HRESULT hr;
823 UINT i, j;
825 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
826 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
827 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
828 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
830 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
831 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
832 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
834 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
835 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836 for(j = 0; j < 2; ++j)
838 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
840 DWORD color;
842 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
843 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
845 hr = IDirect3DDevice9_BeginScene(device);
846 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
849 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
851 hr = IDirect3DDevice9_EndScene(device);
852 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
854 color = getPixelColor(device, 320, 240);
855 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
856 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
858 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
859 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
861 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
862 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
864 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
865 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
868 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
869 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
871 IDirect3DVertexDeclaration9_Release(vertex_declaration);
872 IDirect3DVertexShader9_Release(mova_shader);
873 IDirect3DVertexShader9_Release(mov_shader);
876 struct sVertex {
877 float x, y, z;
878 DWORD diffuse;
879 DWORD specular;
882 struct sVertexT {
883 float x, y, z, rhw;
884 DWORD diffuse;
885 DWORD specular;
888 static void fog_test(IDirect3DDevice9 *device)
890 HRESULT hr;
891 D3DCOLOR color;
892 float start = 0.0f, end = 1.0f;
893 D3DCAPS9 caps;
894 int i;
896 /* Gets full z based fog with linear fog, no fog with specular color */
897 struct sVertex untransformed_1[] = {
898 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
899 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
900 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
901 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
903 /* Ok, I am too lazy to deal with transform matrices */
904 struct sVertex untransformed_2[] = {
905 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
906 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
907 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
908 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
910 /* Untransformed ones. Give them a different diffuse color to make the test look
911 * nicer. It also makes making sure that they are drawn correctly easier.
913 struct sVertexT transformed_1[] = {
914 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
915 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
916 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
917 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
919 struct sVertexT transformed_2[] = {
920 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
921 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
922 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
923 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
925 struct vertex rev_fog_quads[] = {
926 {-1.0, -1.0, 0.1, 0x000000ff},
927 {-1.0, 0.0, 0.1, 0x000000ff},
928 { 0.0, 0.0, 0.1, 0x000000ff},
929 { 0.0, -1.0, 0.1, 0x000000ff},
931 { 0.0, -1.0, 0.9, 0x000000ff},
932 { 0.0, 0.0, 0.9, 0x000000ff},
933 { 1.0, 0.0, 0.9, 0x000000ff},
934 { 1.0, -1.0, 0.9, 0x000000ff},
936 { 0.0, 0.0, 0.4, 0x000000ff},
937 { 0.0, 1.0, 0.4, 0x000000ff},
938 { 1.0, 1.0, 0.4, 0x000000ff},
939 { 1.0, 0.0, 0.4, 0x000000ff},
941 {-1.0, 0.0, 0.7, 0x000000ff},
942 {-1.0, 1.0, 0.7, 0x000000ff},
943 { 0.0, 1.0, 0.7, 0x000000ff},
944 { 0.0, 0.0, 0.7, 0x000000ff},
946 WORD Indices[] = {0, 1, 2, 2, 3, 0};
948 const float ident_mat[16] =
950 1.0f, 0.0f, 0.0f, 0.0f,
951 0.0f, 1.0f, 0.0f, 0.0f,
952 0.0f, 0.0f, 1.0f, 0.0f,
953 0.0f, 0.0f, 0.0f, 1.0f
955 const float world_mat1[16] =
957 1.0f, 0.0f, 0.0f, 0.0f,
958 0.0f, 1.0f, 0.0f, 0.0f,
959 0.0f, 0.0f, 1.0f, 0.0f,
960 0.0f, 0.0f, -0.5f, 1.0f
962 const float world_mat2[16] =
964 1.0f, 0.0f, 0.0f, 0.0f,
965 0.0f, 1.0f, 0.0f, 0.0f,
966 0.0f, 0.0f, 1.0f, 0.0f,
967 0.0f, 0.0f, 1.0f, 1.0f
969 const float proj_mat[16] =
971 1.0f, 0.0f, 0.0f, 0.0f,
972 0.0f, 1.0f, 0.0f, 0.0f,
973 0.0f, 0.0f, 1.0f, 0.0f,
974 0.0f, 0.0f, -1.0f, 1.0f
977 const struct sVertex far_quad1[] =
979 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
980 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
981 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
982 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
984 const struct sVertex far_quad2[] =
986 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
987 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
988 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
989 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
992 memset(&caps, 0, sizeof(caps));
993 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
994 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
996 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
998 /* Setup initial states: No lighting, fog on, fog color */
999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1000 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1002 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1004 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1006 /* First test: Both table fog and vertex fog off */
1007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1008 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1010 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1012 /* Start = 0, end = 1. Should be default, but set them */
1013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1014 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1016 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1018 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1020 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1021 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1022 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1023 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1024 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1025 sizeof(untransformed_1[0]));
1026 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1028 /* That makes it use the Z value */
1029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1030 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1031 /* Untransformed, vertex fog != none (or table fog != none):
1032 * Use the Z value as input into the equation
1034 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1035 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1036 sizeof(untransformed_2[0]));
1037 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039 /* transformed verts */
1040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1043 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1044 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1045 sizeof(transformed_1[0]));
1046 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1049 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1050 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1051 * equation
1053 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1055 sizeof(transformed_2[0]));
1056 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1058 hr = IDirect3DDevice9_EndScene(device);
1059 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1061 else
1063 ok(FALSE, "BeginScene failed\n");
1066 color = getPixelColor(device, 160, 360);
1067 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1068 color = getPixelColor(device, 160, 120);
1069 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1070 color = getPixelColor(device, 480, 120);
1071 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1072 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1074 color = getPixelColor(device, 480, 360);
1075 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1077 else
1079 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1080 * The settings above result in no fogging with vertex fog
1082 color = getPixelColor(device, 480, 120);
1083 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1084 trace("Info: Table fog not supported by this device\n");
1086 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1088 /* Now test the special case fogstart == fogend */
1089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1090 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1092 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1094 start = 512;
1095 end = 512;
1096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1097 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1099 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1101 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1102 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1104 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1106 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1108 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1109 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1110 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1111 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1112 * color and has fixed fogstart and fogend.
1114 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1115 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1116 sizeof(untransformed_1[0]));
1117 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1118 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1119 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1120 sizeof(untransformed_2[0]));
1121 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1123 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1124 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1125 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1126 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1127 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1128 sizeof(transformed_1[0]));
1129 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1131 hr = IDirect3DDevice9_EndScene(device);
1132 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1134 else
1136 ok(FALSE, "BeginScene failed\n");
1138 color = getPixelColor(device, 160, 360);
1139 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1140 color = getPixelColor(device, 160, 120);
1141 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1142 color = getPixelColor(device, 480, 120);
1143 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1144 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1146 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1147 * but without shaders it seems to work everywhere
1149 end = 0.2;
1150 start = 0.8;
1151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1152 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1154 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1155 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1156 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1158 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1159 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1160 * so skip this for now
1162 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1163 const char *mode = (i ? "table" : "vertex");
1164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1165 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1167 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1169 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1170 hr = IDirect3DDevice9_BeginScene(device);
1171 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1172 if(SUCCEEDED(hr)) {
1173 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1174 4, 5, 6, 6, 7, 4,
1175 8, 9, 10, 10, 11, 8,
1176 12, 13, 14, 14, 15, 12};
1178 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1179 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1180 sizeof(rev_fog_quads[0]));
1181 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1183 hr = IDirect3DDevice9_EndScene(device);
1184 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1186 color = getPixelColor(device, 160, 360);
1187 ok(color_match(color, 0x0000ff00, 1),
1188 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1190 color = getPixelColor(device, 160, 120);
1191 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1192 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1194 color = getPixelColor(device, 480, 120);
1195 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1196 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1198 color = getPixelColor(device, 480, 360);
1199 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1201 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1203 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1204 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1205 break;
1209 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1211 /* A simple fog + non-identity world matrix test */
1212 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1213 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1215 start = 0.0;
1216 end = 1.0;
1217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1218 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1220 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1222 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1224 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1226 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1227 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1229 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1231 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1232 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1234 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1235 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1236 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1238 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1239 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1240 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1242 hr = IDirect3DDevice9_EndScene(device);
1243 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1245 else
1247 ok(FALSE, "BeginScene failed\n");
1250 color = getPixelColor(device, 160, 360);
1251 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1252 "Unfogged quad has color %08x\n", color);
1253 color = getPixelColor(device, 160, 120);
1254 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1255 "Fogged out quad has color %08x\n", color);
1257 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1259 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1260 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1261 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1262 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1263 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1266 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1268 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1270 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1271 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1273 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1274 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1275 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1277 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1278 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1279 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1281 hr = IDirect3DDevice9_EndScene(device);
1282 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1284 else
1286 ok(FALSE, "BeginScene failed\n");
1289 color = getPixelColor(device, 160, 360);
1290 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1291 color = getPixelColor(device, 160, 120);
1292 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1293 "Fogged out quad has color %08x\n", color);
1295 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1298 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1299 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1300 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1302 else
1304 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1307 /* Test RANGEFOG vs FOGTABLEMODE */
1308 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1309 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1311 struct sVertex untransformed_3[] =
1313 {-1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1314 {-1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1315 { 1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1316 { 1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1319 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1320 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1321 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1322 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1325 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1327 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1328 * is not used, the fog coordinate will be equal to fogstart and the quad not
1329 * fogged. If range fog is used the fog coordinate will be slightly higher and
1330 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1331 * is calculated per vertex and interpolated, so even the center of the screen
1332 * where the difference doesn't matter will be fogged, but check the corners in
1333 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1334 start = 0.5f;
1335 end = 0.50001f;
1336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1337 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1339 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1341 /* Table fog: Range fog is not used */
1342 hr = IDirect3DDevice9_BeginScene(device);
1343 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1344 if (SUCCEEDED(hr))
1346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1347 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1349 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1350 hr = IDirect3DDevice9_EndScene(device);
1351 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1353 color = getPixelColor(device, 10, 10);
1354 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1355 color = getPixelColor(device, 630, 10);
1356 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1357 color = getPixelColor(device, 10, 470);
1358 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1359 color = getPixelColor(device, 630, 470);
1360 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1362 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1363 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1365 /* Vertex fog: Rangefog is used */
1366 hr = IDirect3DDevice9_BeginScene(device);
1367 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1368 if (SUCCEEDED(hr))
1370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1371 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1373 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1375 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1376 hr = IDirect3DDevice9_EndScene(device);
1377 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1379 color = getPixelColor(device, 10, 10);
1380 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1381 "Rangefog with vertex fog returned color 0x%08x\n", color);
1382 color = getPixelColor(device, 630, 10);
1383 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1384 "Rangefog with vertex fog returned color 0x%08x\n", color);
1385 color = getPixelColor(device, 10, 470);
1386 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1387 "Rangefog with vertex fog returned color 0x%08x\n", color);
1388 color = getPixelColor(device, 630, 470);
1389 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1390 "Rangefog with vertex fog returned color 0x%08x\n", color);
1392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1393 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1396 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1398 else
1400 skip("Range fog or table fog not supported, skipping range fog tests\n");
1403 /* Turn off the fog master switch to avoid confusing other tests */
1404 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1405 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1406 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1407 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1409 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1412 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1413 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1414 * regardless of the actual addressing mode set. The way this test works is
1415 * that we sample in one of the corners of the cubemap with filtering enabled,
1416 * and check the interpolated color. There are essentially two reasonable
1417 * things an implementation can do: Either pick one of the faces and
1418 * interpolate the edge texel with itself (i.e., clamp within the face), or
1419 * interpolate between the edge texels of the three involved faces. It should
1420 * never involve the border color or the other side (texcoord wrapping) of a
1421 * face in the interpolation. */
1422 static void test_cube_wrap(IDirect3DDevice9 *device)
1424 static const float quad[][6] = {
1425 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1426 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1427 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1428 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1431 static const D3DVERTEXELEMENT9 decl_elements[] = {
1432 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1433 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1434 D3DDECL_END()
1437 static const struct {
1438 D3DTEXTUREADDRESS mode;
1439 const char *name;
1440 } address_modes[] = {
1441 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1442 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1443 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1444 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1445 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1448 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1449 IDirect3DCubeTexture9 *texture = NULL;
1450 IDirect3DSurface9 *surface = NULL;
1451 IDirect3DSurface9 *face_surface;
1452 D3DLOCKED_RECT locked_rect;
1453 HRESULT hr;
1454 UINT x;
1455 INT y, face;
1457 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1458 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1459 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1460 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1462 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1463 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1464 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1466 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1467 D3DPOOL_DEFAULT, &texture, NULL);
1468 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1470 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1471 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1473 for (y = 0; y < 128; ++y)
1475 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1476 for (x = 0; x < 64; ++x)
1478 *ptr++ = 0xff0000ff;
1480 for (x = 64; x < 128; ++x)
1482 *ptr++ = 0xffff0000;
1486 hr = IDirect3DSurface9_UnlockRect(surface);
1487 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1489 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1490 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1492 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1493 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1495 IDirect3DSurface9_Release(face_surface);
1497 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1498 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1500 for (y = 0; y < 128; ++y)
1502 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1503 for (x = 0; x < 64; ++x)
1505 *ptr++ = 0xffff0000;
1507 for (x = 64; x < 128; ++x)
1509 *ptr++ = 0xff0000ff;
1513 hr = IDirect3DSurface9_UnlockRect(surface);
1514 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1516 /* Create cube faces */
1517 for (face = 1; face < 6; ++face)
1519 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1520 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1522 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1523 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1525 IDirect3DSurface9_Release(face_surface);
1528 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1529 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1531 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1532 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1533 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1534 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1535 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1536 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1538 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1539 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1541 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1543 DWORD color;
1545 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1546 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1547 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1548 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1550 hr = IDirect3DDevice9_BeginScene(device);
1551 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1553 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1554 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1556 hr = IDirect3DDevice9_EndScene(device);
1557 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1559 color = getPixelColor(device, 320, 240);
1560 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1561 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1562 color, address_modes[x].name);
1564 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1565 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1567 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1568 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1571 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1572 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1574 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1575 IDirect3DCubeTexture9_Release(texture);
1576 IDirect3DSurface9_Release(surface);
1579 static void offscreen_test(IDirect3DDevice9 *device)
1581 HRESULT hr;
1582 IDirect3DTexture9 *offscreenTexture = NULL;
1583 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1584 DWORD color;
1586 static const float quad[][5] = {
1587 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1588 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1589 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1590 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1593 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1594 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1596 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1597 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1598 if(!offscreenTexture) {
1599 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1600 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1601 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1602 if(!offscreenTexture) {
1603 skip("Cannot create an offscreen render target\n");
1604 goto out;
1608 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1609 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1610 if(!backbuffer) {
1611 goto out;
1614 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1615 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1616 if(!offscreen) {
1617 goto out;
1620 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1621 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1623 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1624 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1625 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1626 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1627 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1628 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1629 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1630 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1634 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1635 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1636 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1638 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1640 /* Draw without textures - Should result in a white quad */
1641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1642 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1644 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1645 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1646 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1647 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1649 /* This time with the texture */
1650 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1651 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1653 IDirect3DDevice9_EndScene(device);
1656 /* Center quad - should be white */
1657 color = getPixelColor(device, 320, 240);
1658 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1659 /* Some quad in the cleared part of the texture */
1660 color = getPixelColor(device, 170, 240);
1661 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1662 /* Part of the originally cleared back buffer */
1663 color = getPixelColor(device, 10, 10);
1664 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1665 if(0) {
1666 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1667 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1668 * the offscreen rendering mode this test would succeed or fail
1670 color = getPixelColor(device, 10, 470);
1671 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1674 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1676 out:
1677 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1678 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1680 /* restore things */
1681 if(backbuffer) {
1682 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1683 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1684 IDirect3DSurface9_Release(backbuffer);
1686 if(offscreenTexture) {
1687 IDirect3DTexture9_Release(offscreenTexture);
1689 if(offscreen) {
1690 IDirect3DSurface9_Release(offscreen);
1694 /* This test tests fog in combination with shaders.
1695 * What's tested: linear fog (vertex and table) with pixel shader
1696 * linear table fog with non foggy vertex shader
1697 * vertex fog with foggy vertex shader, non-linear
1698 * fog with shader, non-linear fog with foggy shader,
1699 * linear table fog with foggy shader
1701 static void fog_with_shader_test(IDirect3DDevice9 *device)
1703 HRESULT hr;
1704 DWORD color;
1705 union {
1706 float f;
1707 DWORD i;
1708 } start, end;
1709 unsigned int i, j;
1711 /* basic vertex shader without fog computation ("non foggy") */
1712 static const DWORD vertex_shader_code1[] = {
1713 0xfffe0101, /* vs_1_1 */
1714 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1715 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1716 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1717 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1718 0x0000ffff
1720 /* basic vertex shader with reversed fog computation ("foggy") */
1721 static const DWORD vertex_shader_code2[] = {
1722 0xfffe0101, /* vs_1_1 */
1723 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1724 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1725 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1726 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1727 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1728 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1729 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1730 0x0000ffff
1732 /* basic pixel shader */
1733 static const DWORD pixel_shader_code[] = {
1734 0xffff0101, /* ps_1_1 */
1735 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1736 0x0000ffff
1739 static struct vertex quad[] = {
1740 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1741 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1742 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1743 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1746 static const D3DVERTEXELEMENT9 decl_elements[] = {
1747 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1748 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1749 D3DDECL_END()
1752 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1753 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1754 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1756 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1757 static const struct test_data_t {
1758 int vshader;
1759 int pshader;
1760 D3DFOGMODE vfog;
1761 D3DFOGMODE tfog;
1762 unsigned int color[11];
1763 } test_data[] = {
1764 /* only pixel shader: */
1765 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1766 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1767 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1768 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1769 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1770 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1771 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1772 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1773 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1774 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1775 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1776 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1777 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1778 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1779 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1781 /* vertex shader */
1782 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1783 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1784 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1785 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1786 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1787 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1788 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1789 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1790 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1792 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1793 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1794 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1795 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1796 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1797 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1799 /* vertex shader and pixel shader */
1800 /* The next 4 tests would read the fog coord output, but it isn't available.
1801 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1802 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1803 * These tests should be disabled if some other hardware behaves differently
1805 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1806 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1807 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1808 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1810 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1811 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1812 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1813 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1814 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1815 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1816 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1818 /* These use the Z coordinate with linear table fog */
1819 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1820 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1823 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1825 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1826 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1827 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1828 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1829 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1830 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832 /* Non-linear table fog without fog coord */
1833 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1834 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1835 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1836 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1837 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1838 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1840 #if 0 /* FIXME: these fail on GeForce 8500 */
1841 /* foggy vertex shader */
1842 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1843 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1844 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1845 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1846 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1847 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1848 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1849 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1850 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1851 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1852 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1853 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1854 #endif
1856 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1857 * all using the fixed fog-coord linear fog
1859 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1860 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1861 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1862 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1863 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1864 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1865 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1866 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1867 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1868 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1869 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1870 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1872 /* These use table fog. Here the shader-provided fog coordinate is
1873 * ignored and the z coordinate used instead
1875 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1876 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1877 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1878 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1879 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1880 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1881 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1882 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1883 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1886 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1887 start.f=0.1f;
1888 end.f=0.9f;
1890 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1891 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1892 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1893 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1894 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1895 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1896 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1897 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1899 /* Setup initial states: No lighting, fog on, fog color */
1900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1901 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1903 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1905 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1906 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1907 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1910 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1912 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1914 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1916 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1918 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1920 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1922 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1923 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1924 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1925 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1927 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1929 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1931 for(j=0; j < 11; j++)
1933 /* Don't use the whole zrange to prevent rounding errors */
1934 quad[0].z = 0.001f + (float)j / 10.02f;
1935 quad[1].z = 0.001f + (float)j / 10.02f;
1936 quad[2].z = 0.001f + (float)j / 10.02f;
1937 quad[3].z = 0.001f + (float)j / 10.02f;
1939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1940 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1942 hr = IDirect3DDevice9_BeginScene(device);
1943 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1946 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1948 hr = IDirect3DDevice9_EndScene(device);
1949 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1951 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1952 color = getPixelColor(device, 128, 240);
1953 ok(color_match(color, test_data[i].color[j], 13),
1954 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1955 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1957 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1961 /* reset states */
1962 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1963 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1964 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1965 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1966 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1967 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1969 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1971 IDirect3DVertexShader9_Release(vertex_shader[1]);
1972 IDirect3DVertexShader9_Release(vertex_shader[2]);
1973 IDirect3DPixelShader9_Release(pixel_shader[1]);
1974 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1977 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1978 unsigned int i, x, y;
1979 HRESULT hr;
1980 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1981 D3DLOCKED_RECT locked_rect;
1983 /* Generate the textures */
1984 for(i=0; i<2; i++)
1986 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1987 D3DPOOL_MANAGED, &texture[i], NULL);
1988 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1990 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1991 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1992 for (y = 0; y < 128; ++y)
1994 if(i)
1995 { /* Set up black texture with 2x2 texel white spot in the middle */
1996 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1997 for (x = 0; x < 128; ++x)
1999 if(y>62 && y<66 && x>62 && x<66)
2000 *ptr++ = 0xffffffff;
2001 else
2002 *ptr++ = 0xff000000;
2005 else
2006 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2007 * (if multiplied with bumpenvmat)
2009 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2010 for (x = 0; x < 128; ++x)
2012 if(abs(x-64)>abs(y-64))
2014 if(x < 64)
2015 *ptr++ = 0xc000;
2016 else
2017 *ptr++ = 0x4000;
2019 else
2021 if(y < 64)
2022 *ptr++ = 0x0040;
2023 else
2024 *ptr++ = 0x00c0;
2029 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2030 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2032 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2033 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2035 /* Disable texture filtering */
2036 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2037 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2038 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2039 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2041 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2042 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2043 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2044 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2048 /* test the behavior of the texbem instruction
2049 * with normal 2D and projective 2D textures
2051 static void texbem_test(IDirect3DDevice9 *device)
2053 HRESULT hr;
2054 DWORD color;
2055 int i;
2057 static const DWORD pixel_shader_code[] = {
2058 0xffff0101, /* ps_1_1*/
2059 0x00000042, 0xb00f0000, /* tex t0*/
2060 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2061 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2062 0x0000ffff
2064 static const DWORD double_texbem_code[] = {
2065 0xffff0103, /* ps_1_3 */
2066 0x00000042, 0xb00f0000, /* tex t0 */
2067 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2068 0x00000042, 0xb00f0002, /* tex t2 */
2069 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2070 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2071 0x0000ffff /* end */
2075 static const float quad[][7] = {
2076 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2077 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2078 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2079 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2081 static const float quad_proj[][9] = {
2082 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2083 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2084 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2085 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2088 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2089 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2090 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2091 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2092 D3DDECL_END()
2094 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2095 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2096 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2097 D3DDECL_END()
2098 } };
2100 /* use asymmetric matrix to test loading */
2101 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2103 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2104 IDirect3DPixelShader9 *pixel_shader = NULL;
2105 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
2106 D3DLOCKED_RECT locked_rect;
2108 generate_bumpmap_textures(device);
2110 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2111 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2112 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2113 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2114 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2116 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2117 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2119 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2120 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2122 for(i=0; i<2; i++)
2124 if(i)
2126 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2127 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2130 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2131 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2132 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2133 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2135 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2136 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2137 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2138 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2140 hr = IDirect3DDevice9_BeginScene(device);
2141 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2143 if(!i)
2144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2145 else
2146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2147 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2149 hr = IDirect3DDevice9_EndScene(device);
2150 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2152 color = getPixelColor(device, 320-32, 240);
2153 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2154 color = getPixelColor(device, 320+32, 240);
2155 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2156 color = getPixelColor(device, 320, 240-32);
2157 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2158 color = getPixelColor(device, 320, 240+32);
2159 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2161 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2162 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2164 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2165 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2166 IDirect3DPixelShader9_Release(pixel_shader);
2168 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2169 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2170 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2173 /* clean up */
2174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2175 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2177 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2178 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2180 for(i=0; i<2; i++)
2182 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2183 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2184 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2185 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2186 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2187 IDirect3DTexture9_Release(texture);
2190 /* Test double texbem */
2191 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2192 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2193 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2194 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2195 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2196 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2197 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2198 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2200 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2201 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2202 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2203 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2205 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2206 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2208 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2209 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2210 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2211 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2212 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2213 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2216 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2217 #define tex 0x00ff0000
2218 #define tex1 0x0000ff00
2219 #define origin 0x000000ff
2220 static const DWORD pixel_data[] = {
2221 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2222 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2223 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2224 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2225 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2226 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2227 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2228 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2230 #undef tex1
2231 #undef tex2
2232 #undef origin
2234 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2235 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2236 for(i = 0; i < 8; i++) {
2237 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2239 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2240 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2243 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2245 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2247 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2249 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2251 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2252 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2253 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2254 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2256 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2257 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2258 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2260 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2262 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2264 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2267 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2268 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2269 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2270 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2271 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2272 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2273 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2274 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2275 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2276 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2278 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2279 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2281 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2282 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2283 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2284 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2285 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2286 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2287 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2288 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2289 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2290 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2292 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2293 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2295 hr = IDirect3DDevice9_BeginScene(device);
2296 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2297 if(SUCCEEDED(hr)) {
2298 static const float double_quad[] = {
2299 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2300 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2301 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2302 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2306 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2307 hr = IDirect3DDevice9_EndScene(device);
2308 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2310 color = getPixelColor(device, 320, 240);
2311 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2313 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2314 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2315 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2316 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2317 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2318 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2319 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2320 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2321 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2322 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2324 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2325 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2327 IDirect3DPixelShader9_Release(pixel_shader);
2328 IDirect3DTexture9_Release(texture);
2329 IDirect3DTexture9_Release(texture1);
2330 IDirect3DTexture9_Release(texture2);
2333 static void z_range_test(IDirect3DDevice9 *device)
2335 const struct vertex quad[] =
2337 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2338 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2339 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2340 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2342 const struct vertex quad2[] =
2344 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2345 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2346 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2347 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2350 const struct tvertex quad3[] =
2352 { 0, 240, 1.1f, 1.0, 0xffffff00},
2353 { 0, 480, 1.1f, 1.0, 0xffffff00},
2354 { 640, 240, -1.1f, 1.0, 0xffffff00},
2355 { 640, 480, -1.1f, 1.0, 0xffffff00},
2357 const struct tvertex quad4[] =
2359 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2360 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2361 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2362 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2364 HRESULT hr;
2365 DWORD color;
2366 IDirect3DVertexShader9 *shader;
2367 IDirect3DVertexDeclaration9 *decl;
2368 D3DCAPS9 caps;
2369 const DWORD shader_code[] = {
2370 0xfffe0101, /* vs_1_1 */
2371 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2372 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2373 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2374 0x0000ffff /* end */
2376 static const D3DVERTEXELEMENT9 decl_elements[] = {
2377 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2378 D3DDECL_END()
2381 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2383 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2384 * then call Present. Then clear the color buffer to make sure it has some defined content
2385 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2386 * by the depth value.
2388 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2389 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2390 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2391 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2393 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2396 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2398 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2400 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2404 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2406 hr = IDirect3DDevice9_BeginScene(device);
2407 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2408 if(hr == D3D_OK)
2410 /* Test the untransformed vertex path */
2411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2412 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2414 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2416 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2418 /* Test the transformed vertex path */
2419 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2420 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2423 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2425 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2427 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2429 hr = IDirect3DDevice9_EndScene(device);
2430 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2433 /* Do not test the exact corner pixels, but go pretty close to them */
2435 /* Clipped because z > 1.0 */
2436 color = getPixelColor(device, 28, 238);
2437 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2438 color = getPixelColor(device, 28, 241);
2439 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2441 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2443 else
2445 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2448 /* Not clipped, > z buffer clear value(0.75) */
2449 color = getPixelColor(device, 31, 238);
2450 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2451 color = getPixelColor(device, 31, 241);
2452 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2453 color = getPixelColor(device, 100, 238);
2454 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2455 color = getPixelColor(device, 100, 241);
2456 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2458 /* Not clipped, < z buffer clear value */
2459 color = getPixelColor(device, 104, 238);
2460 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2461 color = getPixelColor(device, 104, 241);
2462 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2463 color = getPixelColor(device, 318, 238);
2464 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2465 color = getPixelColor(device, 318, 241);
2466 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2468 /* Clipped because z < 0.0 */
2469 color = getPixelColor(device, 321, 238);
2470 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2471 color = getPixelColor(device, 321, 241);
2472 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2474 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2476 else
2478 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2481 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2482 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2484 /* Test the shader path */
2485 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2486 skip("Vertex shaders not supported\n");
2487 goto out;
2489 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2490 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2491 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2492 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2496 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2497 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2498 IDirect3DDevice9_SetVertexShader(device, shader);
2499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2501 hr = IDirect3DDevice9_BeginScene(device);
2502 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2503 if(hr == D3D_OK)
2505 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2506 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2507 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2509 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2511 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2512 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2513 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2514 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2516 hr = IDirect3DDevice9_EndScene(device);
2517 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2520 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2521 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2522 IDirect3DDevice9_SetVertexShader(device, NULL);
2523 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2525 IDirect3DVertexDeclaration9_Release(decl);
2526 IDirect3DVertexShader9_Release(shader);
2528 /* Z < 1.0 */
2529 color = getPixelColor(device, 28, 238);
2530 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2532 /* 1.0 < z < 0.75 */
2533 color = getPixelColor(device, 31, 238);
2534 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2535 color = getPixelColor(device, 100, 238);
2536 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2538 /* 0.75 < z < 0.0 */
2539 color = getPixelColor(device, 104, 238);
2540 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2541 color = getPixelColor(device, 318, 238);
2542 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2544 /* 0.0 < z */
2545 color = getPixelColor(device, 321, 238);
2546 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2548 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2549 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2551 out:
2552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2553 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2555 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2560 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2562 D3DSURFACE_DESC desc;
2563 D3DLOCKED_RECT l;
2564 HRESULT hr;
2565 unsigned int x, y;
2566 DWORD *mem;
2568 memset(&desc, 0, sizeof(desc));
2569 memset(&l, 0, sizeof(l));
2570 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2571 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2572 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2573 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2574 if(FAILED(hr)) return;
2576 for(y = 0; y < desc.Height; y++)
2578 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2579 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2581 mem[x] = color;
2584 hr = IDirect3DSurface9_UnlockRect(surface);
2585 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2588 /* This tests a variety of possible StretchRect() situations */
2589 static void stretchrect_test(IDirect3DDevice9 *device)
2591 HRESULT hr;
2592 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2593 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2594 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2595 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2596 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2597 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2598 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2599 IDirect3DSurface9 *orig_rt = NULL;
2600 IDirect3DSurface9 *backbuffer = NULL;
2601 DWORD color;
2603 RECT src_rect64 = {0, 0, 64, 64};
2604 RECT src_rect64_flipy = {0, 64, 64, 0};
2605 RECT dst_rect64 = {0, 0, 64, 64};
2606 RECT dst_rect64_flipy = {0, 64, 64, 0};
2608 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2609 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2610 if(!orig_rt) {
2611 goto out;
2614 /* Create our temporary surfaces in system memory */
2615 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2616 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2617 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2618 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2620 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2621 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2622 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2623 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2624 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2625 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2626 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2628 /* Create render target surfaces */
2629 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2630 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2631 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2632 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2633 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2634 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2635 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2636 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2638 /* Create render target textures */
2639 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2640 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2641 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2642 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2643 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2644 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2645 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2646 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2647 if (tex_rt32) {
2648 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2649 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2651 if (tex_rt64) {
2652 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2653 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2655 if (tex_rt_dest64) {
2656 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2657 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2659 if (tex_rt_dest64) {
2660 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2661 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2664 /* Create regular textures in D3DPOOL_DEFAULT */
2665 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2666 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2667 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2668 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2669 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2670 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2671 if (tex32) {
2672 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2673 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2675 if (tex64) {
2676 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2677 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2679 if (tex_dest64) {
2680 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2681 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2684 /*********************************************************************
2685 * Tests for when the source parameter is an offscreen plain surface *
2686 *********************************************************************/
2688 /* Fill the offscreen 64x64 surface with green */
2689 if (surf_offscreen64)
2690 fill_surface(surf_offscreen64, 0xff00ff00);
2692 /* offscreenplain ==> offscreenplain, same size */
2693 if(surf_offscreen64 && surf_offscreen_dest64) {
2694 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2695 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697 if (hr == D3D_OK) {
2698 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2699 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2702 /* Blit without scaling */
2703 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2704 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2706 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2707 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2708 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2710 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2711 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2712 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2715 /* offscreenplain ==> rendertarget texture, same size */
2716 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2717 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2718 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720 /* We can't lock rendertarget textures, so copy to our temp surface first */
2721 if (hr == D3D_OK) {
2722 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2723 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2726 if (hr == D3D_OK) {
2727 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2728 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2731 /* Blit without scaling */
2732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2733 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2735 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2736 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2737 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2739 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2740 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2741 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2744 /* offscreenplain ==> rendertarget surface, same size */
2745 if(surf_offscreen64 && surf_rt_dest64) {
2746 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2747 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2749 if (hr == D3D_OK) {
2750 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2751 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2754 /* Blit without scaling */
2755 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2756 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2758 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2759 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2760 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2762 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2763 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2764 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2767 /* offscreenplain ==> texture, same size (should fail) */
2768 if(surf_offscreen64 && surf_tex_dest64) {
2769 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2770 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2773 /* Fill the smaller offscreen surface with red */
2774 fill_surface(surf_offscreen32, 0xffff0000);
2776 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2777 if(surf_offscreen32 && surf_offscreen64) {
2778 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2779 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2782 /* offscreenplain ==> rendertarget texture, scaling */
2783 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2784 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2785 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2787 /* We can't lock rendertarget textures, so copy to our temp surface first */
2788 if (hr == D3D_OK) {
2789 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2790 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2793 if (hr == D3D_OK) {
2794 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2795 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2799 /* offscreenplain ==> rendertarget surface, scaling */
2800 if(surf_offscreen32 && surf_rt_dest64) {
2801 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2802 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2804 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2805 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2808 /* offscreenplain ==> texture, scaling (should fail) */
2809 if(surf_offscreen32 && surf_tex_dest64) {
2810 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2811 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2814 /************************************************************
2815 * Tests for when the source parameter is a regular texture *
2816 ************************************************************/
2818 /* Fill the surface of the regular texture with blue */
2819 if (surf_tex64 && surf_temp64) {
2820 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2821 fill_surface(surf_temp64, 0xff0000ff);
2822 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2823 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2826 /* texture ==> offscreenplain, same size */
2827 if(surf_tex64 && surf_offscreen64) {
2828 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2829 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2832 /* texture ==> rendertarget texture, same size */
2833 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2834 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2835 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837 /* We can't lock rendertarget textures, so copy to our temp surface first */
2838 if (hr == D3D_OK) {
2839 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2840 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2843 if (hr == D3D_OK) {
2844 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2845 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2848 /* Blit without scaling */
2849 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2850 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2853 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2854 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2857 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2858 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861 /* texture ==> rendertarget surface, same size */
2862 if(surf_tex64 && surf_rt_dest64) {
2863 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2864 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2866 if (hr == D3D_OK) {
2867 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2868 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2871 /* Blit without scaling */
2872 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2873 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2875 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2876 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2877 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2879 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2880 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2881 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2884 /* texture ==> texture, same size (should fail) */
2885 if(surf_tex64 && surf_tex_dest64) {
2886 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2887 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2890 /* Fill the surface of the smaller regular texture with red */
2891 if (surf_tex32 && surf_temp32) {
2892 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2893 fill_surface(surf_temp32, 0xffff0000);
2894 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2895 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2898 /* texture ==> offscreenplain, scaling (should fail) */
2899 if(surf_tex32 && surf_offscreen64) {
2900 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2901 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904 /* texture ==> rendertarget texture, scaling */
2905 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2906 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2907 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2909 /* We can't lock rendertarget textures, so copy to our temp surface first */
2910 if (hr == D3D_OK) {
2911 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2912 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2915 if (hr == D3D_OK) {
2916 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2917 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2921 /* texture ==> rendertarget surface, scaling */
2922 if(surf_tex32 && surf_rt_dest64) {
2923 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2924 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2926 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2927 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2930 /* texture ==> texture, scaling (should fail) */
2931 if(surf_tex32 && surf_tex_dest64) {
2932 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2933 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2936 /*****************************************************************
2937 * Tests for when the source parameter is a rendertarget texture *
2938 *****************************************************************/
2940 /* Fill the surface of the rendertarget texture with white */
2941 if (surf_tex_rt64 && surf_temp64) {
2942 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2943 fill_surface(surf_temp64, 0xffffffff);
2944 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2945 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2948 /* rendertarget texture ==> offscreenplain, same size */
2949 if(surf_tex_rt64 && surf_offscreen64) {
2950 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2951 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2954 /* rendertarget texture ==> rendertarget texture, same size */
2955 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2956 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2957 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2959 /* We can't lock rendertarget textures, so copy to our temp surface first */
2960 if (hr == D3D_OK) {
2961 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2962 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2965 if (hr == D3D_OK) {
2966 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2967 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2970 /* Blit without scaling */
2971 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2972 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2974 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2975 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2976 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2978 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2979 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2980 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2983 /* rendertarget texture ==> rendertarget surface, same size */
2984 if(surf_tex_rt64 && surf_rt_dest64) {
2985 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2986 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2988 if (hr == D3D_OK) {
2989 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2990 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2993 /* Blit without scaling */
2994 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2995 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2997 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2998 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2999 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3001 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3002 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3003 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3006 /* rendertarget texture ==> texture, same size (should fail) */
3007 if(surf_tex_rt64 && surf_tex_dest64) {
3008 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3009 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3012 /* Fill the surface of the smaller rendertarget texture with red */
3013 if (surf_tex_rt32 && surf_temp32) {
3014 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3015 fill_surface(surf_temp32, 0xffff0000);
3016 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3017 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3020 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3021 if(surf_tex_rt32 && surf_offscreen64) {
3022 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3023 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3026 /* rendertarget texture ==> rendertarget texture, scaling */
3027 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3028 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3029 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3031 /* We can't lock rendertarget textures, so copy to our temp surface first */
3032 if (hr == D3D_OK) {
3033 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3034 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3037 if (hr == D3D_OK) {
3038 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3039 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3043 /* rendertarget texture ==> rendertarget surface, scaling */
3044 if(surf_tex_rt32 && surf_rt_dest64) {
3045 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3046 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3048 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3049 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3052 /* rendertarget texture ==> texture, scaling (should fail) */
3053 if(surf_tex_rt32 && surf_tex_dest64) {
3054 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3055 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3058 /*****************************************************************
3059 * Tests for when the source parameter is a rendertarget surface *
3060 *****************************************************************/
3062 /* Fill the surface of the rendertarget surface with black */
3063 if (surf_rt64)
3064 fill_surface(surf_rt64, 0xff000000);
3066 /* rendertarget texture ==> offscreenplain, same size */
3067 if(surf_rt64 && surf_offscreen64) {
3068 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3069 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3072 /* rendertarget surface ==> rendertarget texture, same size */
3073 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3074 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3075 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3077 /* We can't lock rendertarget textures, so copy to our temp surface first */
3078 if (hr == D3D_OK) {
3079 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3080 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3083 if (hr == D3D_OK) {
3084 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3085 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3088 /* Blit without scaling */
3089 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3090 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3092 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3093 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3094 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3096 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3097 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3098 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3101 /* rendertarget surface ==> rendertarget surface, same size */
3102 if(surf_rt64 && surf_rt_dest64) {
3103 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3104 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3106 if (hr == D3D_OK) {
3107 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3108 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3111 /* Blit without scaling */
3112 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3113 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3115 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3116 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3117 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3119 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3120 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3121 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3124 /* rendertarget surface ==> texture, same size (should fail) */
3125 if(surf_rt64 && surf_tex_dest64) {
3126 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3127 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3130 /* Fill the surface of the smaller rendertarget texture with red */
3131 if (surf_rt32)
3132 fill_surface(surf_rt32, 0xffff0000);
3134 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3135 if(surf_rt32 && surf_offscreen64) {
3136 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3137 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3140 /* rendertarget surface ==> rendertarget texture, scaling */
3141 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3142 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3143 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3145 /* We can't lock rendertarget textures, so copy to our temp surface first */
3146 if (hr == D3D_OK) {
3147 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3148 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3151 if (hr == D3D_OK) {
3152 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3153 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3157 /* rendertarget surface ==> rendertarget surface, scaling */
3158 if(surf_rt32 && surf_rt_dest64) {
3159 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3160 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3162 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3163 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3166 /* rendertarget surface ==> texture, scaling (should fail) */
3167 if(surf_rt32 && surf_tex_dest64) {
3168 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3169 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3172 /* backbuffer ==> surface tests (no scaling) */
3173 if(backbuffer && surf_tex_rt_dest640_480)
3175 RECT src_rect = {0, 0, 640, 480};
3176 RECT src_rect_flipy = {0, 480, 640, 0};
3177 RECT dst_rect = {0, 0, 640, 480};
3178 RECT dst_rect_flipy = {0, 480, 640, 0};
3180 /* Blit with NULL rectangles */
3181 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3182 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3184 /* Blit without scaling */
3185 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3186 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3188 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3189 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3190 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3192 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3193 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3194 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3197 /* TODO: Test format conversions */
3200 out:
3201 /* Clean up */
3202 if (backbuffer)
3203 IDirect3DSurface9_Release(backbuffer);
3204 if (surf_rt32)
3205 IDirect3DSurface9_Release(surf_rt32);
3206 if (surf_rt64)
3207 IDirect3DSurface9_Release(surf_rt64);
3208 if (surf_rt_dest64)
3209 IDirect3DSurface9_Release(surf_rt_dest64);
3210 if (surf_temp32)
3211 IDirect3DSurface9_Release(surf_temp32);
3212 if (surf_temp64)
3213 IDirect3DSurface9_Release(surf_temp64);
3214 if (surf_offscreen32)
3215 IDirect3DSurface9_Release(surf_offscreen32);
3216 if (surf_offscreen64)
3217 IDirect3DSurface9_Release(surf_offscreen64);
3218 if (surf_offscreen_dest64)
3219 IDirect3DSurface9_Release(surf_offscreen_dest64);
3221 if (tex_rt32) {
3222 if (surf_tex_rt32)
3223 IDirect3DSurface9_Release(surf_tex_rt32);
3224 IDirect3DTexture9_Release(tex_rt32);
3226 if (tex_rt64) {
3227 if (surf_tex_rt64)
3228 IDirect3DSurface9_Release(surf_tex_rt64);
3229 IDirect3DTexture9_Release(tex_rt64);
3231 if (tex_rt_dest64) {
3232 if (surf_tex_rt_dest64)
3233 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3234 IDirect3DTexture9_Release(tex_rt_dest64);
3236 if (tex_rt_dest640_480) {
3237 if (surf_tex_rt_dest640_480)
3238 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3239 IDirect3DTexture9_Release(tex_rt_dest640_480);
3241 if (tex32) {
3242 if (surf_tex32)
3243 IDirect3DSurface9_Release(surf_tex32);
3244 IDirect3DTexture9_Release(tex32);
3246 if (tex64) {
3247 if (surf_tex64)
3248 IDirect3DSurface9_Release(surf_tex64);
3249 IDirect3DTexture9_Release(tex64);
3251 if (tex_dest64) {
3252 if (surf_tex_dest64)
3253 IDirect3DSurface9_Release(surf_tex_dest64);
3254 IDirect3DTexture9_Release(tex_dest64);
3257 if (orig_rt) {
3258 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3259 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3260 IDirect3DSurface9_Release(orig_rt);
3264 static void maxmip_test(IDirect3DDevice9 *device)
3266 IDirect3DTexture9 *texture = NULL;
3267 IDirect3DSurface9 *surface = NULL;
3268 HRESULT hr;
3269 DWORD color;
3270 static const struct
3272 struct
3274 float x, y, z;
3275 float s, t;
3277 v[4];
3279 quads[] =
3282 {-1.0, -1.0, 0.0, 0.0, 0.0},
3283 {-1.0, 0.0, 0.0, 0.0, 1.0},
3284 { 0.0, -1.0, 0.0, 1.0, 0.0},
3285 { 0.0, 0.0, 0.0, 1.0, 1.0},
3288 { 0.0, -1.0, 0.0, 0.0, 0.0},
3289 { 0.0, 0.0, 0.0, 0.0, 1.0},
3290 { 1.0, -1.0, 0.0, 1.0, 0.0},
3291 { 1.0, 0.0, 0.0, 1.0, 1.0},
3294 { 0.0, 0.0, 0.0, 0.0, 0.0},
3295 { 0.0, 1.0, 0.0, 0.0, 1.0},
3296 { 1.0, 0.0, 0.0, 1.0, 0.0},
3297 { 1.0, 1.0, 0.0, 1.0, 1.0},
3300 {-1.0, 0.0, 0.0, 0.0, 0.0},
3301 {-1.0, 1.0, 0.0, 0.0, 1.0},
3302 { 0.0, 0.0, 0.0, 1.0, 0.0},
3303 { 0.0, 1.0, 0.0, 1.0, 1.0},
3307 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3308 &texture, NULL);
3309 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3310 if(!texture)
3312 skip("Failed to create test texture\n");
3313 return;
3316 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3317 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3318 fill_surface(surface, 0xffff0000);
3319 IDirect3DSurface9_Release(surface);
3320 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3321 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3322 fill_surface(surface, 0xff00ff00);
3323 IDirect3DSurface9_Release(surface);
3324 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3325 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3326 fill_surface(surface, 0xff0000ff);
3327 IDirect3DSurface9_Release(surface);
3329 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3330 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3331 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3332 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3334 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3335 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3338 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3340 hr = IDirect3DDevice9_BeginScene(device);
3341 if(SUCCEEDED(hr))
3343 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3344 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3346 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3348 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3349 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3353 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3354 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3358 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3359 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3361 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3362 hr = IDirect3DDevice9_EndScene(device);
3363 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3366 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3367 color = getPixelColor(device, 160, 360);
3368 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3369 color = getPixelColor(device, 480, 360);
3370 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3371 color = getPixelColor(device, 480, 120);
3372 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3373 color = getPixelColor(device, 160, 120);
3374 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3376 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3378 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3379 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3384 hr = IDirect3DDevice9_BeginScene(device);
3385 if(SUCCEEDED(hr))
3387 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3388 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3389 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3390 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3392 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3393 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3395 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3397 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3398 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3400 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3402 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3403 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3405 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3406 hr = IDirect3DDevice9_EndScene(device);
3407 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3410 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3411 * level 3 (> levels in texture) samples from the highest level in the
3412 * texture (level 2). */
3413 color = getPixelColor(device, 160, 360);
3414 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3415 color = getPixelColor(device, 480, 360);
3416 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3417 color = getPixelColor(device, 480, 120);
3418 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3419 color = getPixelColor(device, 160, 120);
3420 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3421 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3422 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3425 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3427 hr = IDirect3DDevice9_BeginScene(device);
3428 if(SUCCEEDED(hr))
3430 DWORD ret;
3432 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3433 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3434 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3435 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3436 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3437 ret = IDirect3DTexture9_SetLOD(texture, 1);
3438 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3440 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3442 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3443 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3444 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3446 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3447 ret = IDirect3DTexture9_SetLOD(texture, 2);
3448 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3450 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3453 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3454 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455 ret = IDirect3DTexture9_SetLOD(texture, 1);
3456 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3458 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3460 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3461 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3462 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3463 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3464 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3465 ret = IDirect3DTexture9_SetLOD(texture, 1);
3466 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3467 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3468 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3469 hr = IDirect3DDevice9_EndScene(device);
3470 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3473 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3474 * level 3 (> levels in texture) samples from the highest level in the
3475 * texture (level 2). */
3476 color = getPixelColor(device, 160, 360);
3477 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3478 color = getPixelColor(device, 480, 360);
3479 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3480 color = getPixelColor(device, 480, 120);
3481 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3482 color = getPixelColor(device, 160, 120);
3483 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3485 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3486 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3488 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3489 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3490 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3491 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3492 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3493 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494 IDirect3DTexture9_Release(texture);
3497 static void release_buffer_test(IDirect3DDevice9 *device)
3499 IDirect3DVertexBuffer9 *vb = NULL;
3500 IDirect3DIndexBuffer9 *ib = NULL;
3501 HRESULT hr;
3502 BYTE *data;
3503 LONG ref;
3505 static const struct vertex quad[] = {
3506 {-1.0, -1.0, 0.1, 0xffff0000},
3507 {-1.0, 1.0, 0.1, 0xffff0000},
3508 { 1.0, 1.0, 0.1, 0xffff0000},
3510 {-1.0, -1.0, 0.1, 0xff00ff00},
3511 {-1.0, 1.0, 0.1, 0xff00ff00},
3512 { 1.0, 1.0, 0.1, 0xff00ff00}
3514 short indices[] = {3, 4, 5};
3516 /* Index and vertex buffers should always be creatable */
3517 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3518 D3DPOOL_MANAGED, &vb, NULL);
3519 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3520 if(!vb) {
3521 skip("Failed to create a vertex buffer\n");
3522 return;
3524 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3525 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3526 if(!ib) {
3527 skip("Failed to create an index buffer\n");
3528 return;
3531 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3532 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3533 memcpy(data, quad, sizeof(quad));
3534 hr = IDirect3DVertexBuffer9_Unlock(vb);
3535 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3537 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3538 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3539 memcpy(data, indices, sizeof(indices));
3540 hr = IDirect3DIndexBuffer9_Unlock(ib);
3541 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3543 hr = IDirect3DDevice9_SetIndices(device, ib);
3544 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3545 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3546 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3547 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3548 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3550 /* Now destroy the bound index buffer and draw again */
3551 ref = IDirect3DIndexBuffer9_Release(ib);
3552 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3554 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3557 hr = IDirect3DDevice9_BeginScene(device);
3558 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3559 if(SUCCEEDED(hr))
3561 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3562 * making assumptions about the indices or vertices
3564 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3565 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3566 hr = IDirect3DDevice9_EndScene(device);
3567 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3570 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3573 hr = IDirect3DDevice9_SetIndices(device, NULL);
3574 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3575 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3576 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3578 /* Index buffer was already destroyed as part of the test */
3579 IDirect3DVertexBuffer9_Release(vb);
3582 static void float_texture_test(IDirect3DDevice9 *device)
3584 IDirect3D9 *d3d = NULL;
3585 HRESULT hr;
3586 IDirect3DTexture9 *texture = NULL;
3587 D3DLOCKED_RECT lr;
3588 float *data;
3589 DWORD color;
3590 float quad[] = {
3591 -1.0, -1.0, 0.1, 0.0, 0.0,
3592 -1.0, 1.0, 0.1, 0.0, 1.0,
3593 1.0, -1.0, 0.1, 1.0, 0.0,
3594 1.0, 1.0, 0.1, 1.0, 1.0,
3597 memset(&lr, 0, sizeof(lr));
3598 IDirect3DDevice9_GetDirect3D(device, &d3d);
3599 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3600 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3601 skip("D3DFMT_R32F textures not supported\n");
3602 goto out;
3605 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3606 D3DPOOL_MANAGED, &texture, NULL);
3607 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3608 if(!texture) {
3609 skip("Failed to create R32F texture\n");
3610 goto out;
3613 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3614 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3615 data = lr.pBits;
3616 *data = 0.0;
3617 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3618 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3620 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3621 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3623 hr = IDirect3DDevice9_BeginScene(device);
3624 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3625 if(SUCCEEDED(hr))
3627 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3628 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3631 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3633 hr = IDirect3DDevice9_EndScene(device);
3634 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3636 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3637 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3639 color = getPixelColor(device, 240, 320);
3640 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3642 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3643 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3645 out:
3646 if(texture) IDirect3DTexture9_Release(texture);
3647 IDirect3D9_Release(d3d);
3650 static void g16r16_texture_test(IDirect3DDevice9 *device)
3652 IDirect3D9 *d3d = NULL;
3653 HRESULT hr;
3654 IDirect3DTexture9 *texture = NULL;
3655 D3DLOCKED_RECT lr;
3656 DWORD *data;
3657 DWORD color;
3658 float quad[] = {
3659 -1.0, -1.0, 0.1, 0.0, 0.0,
3660 -1.0, 1.0, 0.1, 0.0, 1.0,
3661 1.0, -1.0, 0.1, 1.0, 0.0,
3662 1.0, 1.0, 0.1, 1.0, 1.0,
3665 memset(&lr, 0, sizeof(lr));
3666 IDirect3DDevice9_GetDirect3D(device, &d3d);
3667 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3668 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3669 skip("D3DFMT_G16R16 textures not supported\n");
3670 goto out;
3673 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3674 D3DPOOL_MANAGED, &texture, NULL);
3675 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3676 if(!texture) {
3677 skip("Failed to create D3DFMT_G16R16 texture\n");
3678 goto out;
3681 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3682 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3683 data = lr.pBits;
3684 *data = 0x0f00f000;
3685 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3686 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3688 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3689 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3691 hr = IDirect3DDevice9_BeginScene(device);
3692 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3693 if(SUCCEEDED(hr))
3695 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3696 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3698 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3699 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3701 hr = IDirect3DDevice9_EndScene(device);
3702 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3704 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3705 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3707 color = getPixelColor(device, 240, 320);
3708 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3709 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3712 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3714 out:
3715 if(texture) IDirect3DTexture9_Release(texture);
3716 IDirect3D9_Release(d3d);
3719 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3721 LONG x_coords[2][2] =
3723 {r.left - 1, r.left + 1},
3724 {r.right + 1, r.right - 1},
3726 LONG y_coords[2][2] =
3728 {r.top - 1, r.top + 1},
3729 {r.bottom + 1, r.bottom - 1}
3731 unsigned int i, j, x_side, y_side;
3733 for (i = 0; i < 2; ++i)
3735 for (j = 0; j < 2; ++j)
3737 for (x_side = 0; x_side < 2; ++x_side)
3739 for (y_side = 0; y_side < 2; ++y_side)
3741 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3742 DWORD color;
3743 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3745 color = getPixelColor(device, x, y);
3746 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3747 message, x, y, color, expected);
3754 struct projected_textures_test_run
3756 const char *message;
3757 DWORD flags;
3758 IDirect3DVertexDeclaration9 *decl;
3759 BOOL vs, ps;
3760 RECT rect;
3763 static void projected_textures_test(IDirect3DDevice9 *device,
3764 struct projected_textures_test_run tests[4])
3766 unsigned int i;
3768 static const DWORD vertex_shader[] =
3770 0xfffe0101, /* vs_1_1 */
3771 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3772 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
3773 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3774 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
3775 0x0000ffff /* end */
3777 static const DWORD pixel_shader[] =
3779 0xffff0103, /* ps_1_3 */
3780 0x00000042, 0xb00f0000, /* tex t0 */
3781 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3782 0x0000ffff /* end */
3784 IDirect3DVertexShader9 *vs = NULL;
3785 IDirect3DPixelShader9 *ps = NULL;
3786 HRESULT hr;
3788 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3789 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3790 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3791 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3793 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3794 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3796 hr = IDirect3DDevice9_BeginScene(device);
3797 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3798 if (FAILED(hr))
3799 return;
3801 for (i = 0; i < 4; ++i)
3803 DWORD value = 0xdeadbeef;
3804 static const float proj_quads[] =
3806 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3807 0.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3808 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3809 0.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3811 0.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3812 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3813 0.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3814 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3816 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3817 0.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3818 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3819 0.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3821 0.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3822 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3823 0.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3824 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3827 if (tests[i].vs)
3828 hr = IDirect3DDevice9_SetVertexShader(device, vs);
3829 else
3830 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3831 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3832 if (tests[i].ps)
3833 hr = IDirect3DDevice9_SetPixelShader(device, ps);
3834 else
3835 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3836 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3838 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3839 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3841 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3842 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3843 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3844 ok(SUCCEEDED(hr) && value == tests[i].flags,
3845 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3848 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3849 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3852 hr = IDirect3DDevice9_EndScene(device);
3853 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3855 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3856 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3857 IDirect3DVertexShader9_Release(vs);
3858 IDirect3DPixelShader9_Release(ps);
3860 for (i = 0; i < 4; ++i)
3861 check_rect(device, tests[i].rect, tests[i].message);
3863 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3864 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3867 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3869 HRESULT hr;
3870 IDirect3D9 *d3d;
3871 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3872 D3DCAPS9 caps;
3873 IDirect3DTexture9 *texture = NULL;
3874 IDirect3DVolumeTexture9 *volume = NULL;
3875 unsigned int x, y, z;
3876 D3DLOCKED_RECT lr;
3877 D3DLOCKED_BOX lb;
3878 DWORD color;
3879 UINT w, h;
3880 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3881 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3882 0.0, 1.0, 0.0, 0.0,
3883 0.0, 0.0, 1.0, 0.0,
3884 0.0, 0.0, 0.0, 1.0};
3885 static const D3DVERTEXELEMENT9 decl_elements[] = {
3886 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3887 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3888 D3DDECL_END()
3890 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3891 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3892 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3893 D3DDECL_END()
3895 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3896 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3897 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3898 D3DDECL_END()
3900 static const D3DVERTEXELEMENT9 decl_elements4[] = {
3901 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3902 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3903 D3DDECL_END()
3905 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3906 0x00, 0xff, 0x00, 0x00,
3907 0x00, 0x00, 0x00, 0x00,
3908 0x00, 0x00, 0x00, 0x00};
3910 memset(&lr, 0, sizeof(lr));
3911 memset(&lb, 0, sizeof(lb));
3912 IDirect3DDevice9_GetDirect3D(device, &d3d);
3913 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3914 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3915 fmt = D3DFMT_A16B16G16R16;
3917 IDirect3D9_Release(d3d);
3919 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3920 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3921 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3922 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3923 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3924 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3925 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
3926 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3927 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3928 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3929 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3930 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3931 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3932 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3933 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3934 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3935 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3936 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3937 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3938 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3939 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3940 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3942 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3943 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3946 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3947 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3948 w = min(1024, caps.MaxTextureWidth);
3949 h = min(1024, caps.MaxTextureHeight);
3950 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3951 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3952 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3953 if(!texture) {
3954 skip("Failed to create the test texture\n");
3955 return;
3958 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3959 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3960 * 1.0 in red and green for the x and y coords
3962 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3963 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3964 for(y = 0; y < h; y++) {
3965 for(x = 0; x < w; x++) {
3966 double r_f = (double) y / (double) h;
3967 double g_f = (double) x / (double) w;
3968 if(fmt == D3DFMT_A16B16G16R16) {
3969 unsigned short r, g;
3970 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3971 r = (unsigned short) (r_f * 65536.0);
3972 g = (unsigned short) (g_f * 65536.0);
3973 dst[0] = r;
3974 dst[1] = g;
3975 dst[2] = 0;
3976 dst[3] = 65535;
3977 } else {
3978 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3979 unsigned char r = (unsigned char) (r_f * 255.0);
3980 unsigned char g = (unsigned char) (g_f * 255.0);
3981 dst[0] = 0;
3982 dst[1] = g;
3983 dst[2] = r;
3984 dst[3] = 255;
3988 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3989 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3990 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3991 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3993 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3994 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3995 hr = IDirect3DDevice9_BeginScene(device);
3996 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3997 if(SUCCEEDED(hr))
3999 float quad1[] = {
4000 -1.0, -1.0, 0.1, 1.0, 1.0,
4001 -1.0, 0.0, 0.1, 1.0, 1.0,
4002 0.0, -1.0, 0.1, 1.0, 1.0,
4003 0.0, 0.0, 0.1, 1.0, 1.0,
4005 float quad2[] = {
4006 -1.0, 0.0, 0.1, 1.0, 1.0,
4007 -1.0, 1.0, 0.1, 1.0, 1.0,
4008 0.0, 0.0, 0.1, 1.0, 1.0,
4009 0.0, 1.0, 0.1, 1.0, 1.0,
4011 float quad3[] = {
4012 0.0, 0.0, 0.1, 0.5, 0.5,
4013 0.0, 1.0, 0.1, 0.5, 0.5,
4014 1.0, 0.0, 0.1, 0.5, 0.5,
4015 1.0, 1.0, 0.1, 0.5, 0.5,
4017 float quad4[] = {
4018 320, 480, 0.1, 1.0, 0.0, 1.0,
4019 320, 240, 0.1, 1.0, 0.0, 1.0,
4020 640, 480, 0.1, 1.0, 0.0, 1.0,
4021 640, 240, 0.1, 1.0, 0.0, 1.0,
4023 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4024 0.0, 0.0, 0.0, 0.0,
4025 0.0, 0.0, 0.0, 0.0,
4026 0.0, 0.0, 0.0, 0.0};
4028 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4029 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4030 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4032 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4034 /* What happens with transforms enabled? */
4035 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4036 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4040 /* What happens if 4 coords are used, but only 2 given ?*/
4041 mat[8] = 1.0;
4042 mat[13] = 1.0;
4043 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4044 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4045 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4046 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4048 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4050 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4051 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4052 * due to the coords in the vertices. (turns out red, indeed)
4054 memset(mat, 0, sizeof(mat));
4055 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4056 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4058 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4059 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4064 hr = IDirect3DDevice9_EndScene(device);
4065 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4067 color = getPixelColor(device, 160, 360);
4068 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4069 color = getPixelColor(device, 160, 120);
4070 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4071 color = getPixelColor(device, 480, 120);
4072 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4073 color = getPixelColor(device, 480, 360);
4074 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4075 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4076 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4078 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4079 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4082 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4083 hr = IDirect3DDevice9_BeginScene(device);
4084 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4085 if(SUCCEEDED(hr))
4087 float quad1[] = {
4088 -1.0, -1.0, 0.1, 0.8, 0.2,
4089 -1.0, 0.0, 0.1, 0.8, 0.2,
4090 0.0, -1.0, 0.1, 0.8, 0.2,
4091 0.0, 0.0, 0.1, 0.8, 0.2,
4093 float quad2[] = {
4094 -1.0, 0.0, 0.1, 0.5, 1.0,
4095 -1.0, 1.0, 0.1, 0.5, 1.0,
4096 0.0, 0.0, 0.1, 0.5, 1.0,
4097 0.0, 1.0, 0.1, 0.5, 1.0,
4099 float quad3[] = {
4100 0.0, 0.0, 0.1, 0.5, 1.0,
4101 0.0, 1.0, 0.1, 0.5, 1.0,
4102 1.0, 0.0, 0.1, 0.5, 1.0,
4103 1.0, 1.0, 0.1, 0.5, 1.0,
4105 float quad4[] = {
4106 0.0, -1.0, 0.1, 0.8, 0.2,
4107 0.0, 0.0, 0.1, 0.8, 0.2,
4108 1.0, -1.0, 0.1, 0.8, 0.2,
4109 1.0, 0.0, 0.1, 0.8, 0.2,
4111 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4112 0.0, 0.0, 0.0, 0.0,
4113 0.0, 1.0, 0.0, 0.0,
4114 0.0, 0.0, 0.0, 0.0};
4116 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
4118 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4119 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4120 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4121 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4124 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4126 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4127 * it behaves like COUNT2 because normal textures require 2 coords
4129 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4130 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4132 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4134 /* Just to be sure, the same as quad2 above */
4135 memset(mat, 0, sizeof(mat));
4136 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4138 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4139 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4141 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4143 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4144 * used? And what happens to the first?
4146 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4149 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4151 hr = IDirect3DDevice9_EndScene(device);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4154 color = getPixelColor(device, 160, 360);
4155 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4156 color = getPixelColor(device, 160, 120);
4157 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4158 color = getPixelColor(device, 480, 120);
4159 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4160 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4161 color = getPixelColor(device, 480, 360);
4162 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4163 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4165 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4167 IDirect3DTexture9_Release(texture);
4169 /* Test projected textures, without any fancy matrices */
4170 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4172 if (SUCCEEDED(hr))
4174 struct projected_textures_test_run projected_tests_1[4] =
4177 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4178 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4179 decl3,
4180 FALSE, TRUE,
4181 {120, 300, 240, 390},
4184 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4185 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4186 decl3,
4187 FALSE, TRUE,
4188 {400, 360, 480, 420},
4190 /* Try with some invalid values */
4192 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4193 0xffffffff,
4194 decl3,
4195 FALSE, TRUE,
4196 {120, 60, 240, 150}
4199 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4200 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4201 decl4,
4202 FALSE, TRUE,
4203 {340, 210, 360, 225},
4206 struct projected_textures_test_run projected_tests_2[4] =
4209 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4210 D3DTTFF_PROJECTED,
4211 decl3,
4212 FALSE, TRUE,
4213 {120, 300, 240, 390},
4216 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4217 D3DTTFF_PROJECTED,
4218 decl,
4219 FALSE, TRUE,
4220 {400, 360, 480, 420},
4223 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4224 0xffffffff,
4225 decl,
4226 FALSE, TRUE,
4227 {80, 120, 160, 180},
4230 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4231 D3DTTFF_COUNT1,
4232 decl4,
4233 FALSE, TRUE,
4234 {340, 210, 360, 225},
4237 struct projected_textures_test_run projected_tests_3[4] =
4240 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4241 D3DTTFF_PROJECTED,
4242 decl3,
4243 TRUE, TRUE,
4244 {120, 300, 240, 390},
4247 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, the w component has the default value 1.0) - bottom right",
4248 D3DTTFF_PROJECTED,
4249 decl,
4250 TRUE, TRUE,
4251 {340, 450, 360, 465},
4254 "0xffffffff (like COUNT4 | PROJECTED, the w component has the default value 1.0) - top left",
4255 0xffffffff,
4256 decl,
4257 TRUE, TRUE,
4258 {20, 210, 40, 225},
4261 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4262 D3DTTFF_PROJECTED,
4263 decl3,
4264 FALSE, FALSE,
4265 {440, 60, 560, 150},
4269 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4272 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4273 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4274 for(x = 0; x < 4; x++) {
4275 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4277 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4278 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4279 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4280 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4282 projected_textures_test(device, projected_tests_1);
4283 projected_textures_test(device, projected_tests_2);
4284 projected_textures_test(device, projected_tests_3);
4286 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4287 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4288 IDirect3DTexture9_Release(texture);
4291 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4292 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4293 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4294 * Thus watch out if sampling from texels between 0 and 1.
4296 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4297 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4298 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4299 if(!volume) {
4300 skip("Failed to create a volume texture\n");
4301 goto out;
4304 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4305 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4306 for(z = 0; z < 32; z++) {
4307 for(y = 0; y < 32; y++) {
4308 for(x = 0; x < 32; x++) {
4309 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4310 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4311 float r_f = (float) x / 31.0;
4312 float g_f = (float) y / 31.0;
4313 float b_f = (float) z / 31.0;
4315 if(fmt == D3DFMT_A16B16G16R16) {
4316 unsigned short *mem_s = mem;
4317 mem_s[0] = r_f * 65535.0;
4318 mem_s[1] = g_f * 65535.0;
4319 mem_s[2] = b_f * 65535.0;
4320 mem_s[3] = 65535;
4321 } else {
4322 unsigned char *mem_c = mem;
4323 mem_c[0] = b_f * 255.0;
4324 mem_c[1] = g_f * 255.0;
4325 mem_c[2] = r_f * 255.0;
4326 mem_c[3] = 255;
4331 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4332 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4334 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4335 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4337 hr = IDirect3DDevice9_BeginScene(device);
4338 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4339 if(SUCCEEDED(hr))
4341 float quad1[] = {
4342 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4343 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4344 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4345 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4347 float quad2[] = {
4348 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4349 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4350 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4351 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4353 float quad3[] = {
4354 0.0, 0.0, 0.1, 0.0, 0.0,
4355 0.0, 1.0, 0.1, 0.0, 0.0,
4356 1.0, 0.0, 0.1, 0.0, 0.0,
4357 1.0, 1.0, 0.1, 0.0, 0.0
4359 float quad4[] = {
4360 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4361 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4362 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4363 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4365 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4366 0.0, 0.0, 1.0, 0.0,
4367 0.0, 1.0, 0.0, 0.0,
4368 0.0, 0.0, 0.0, 1.0};
4369 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4370 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4372 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4373 * values
4375 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4376 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4377 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4378 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4380 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4382 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4383 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4384 * otherwise the w will be missing(blue).
4385 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4386 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4388 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4391 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4393 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4394 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4395 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4396 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4397 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4401 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4403 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4404 * disable. ATI extends it up to the amount of values needed for the volume texture
4406 memset(mat, 0, sizeof(mat));
4407 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4409 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4410 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4411 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4412 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4414 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4416 hr = IDirect3DDevice9_EndScene(device);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4420 color = getPixelColor(device, 160, 360);
4421 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4422 color = getPixelColor(device, 160, 120);
4423 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4424 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4425 color = getPixelColor(device, 480, 120);
4426 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4427 color = getPixelColor(device, 480, 360);
4428 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4430 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4431 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4433 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4434 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4435 hr = IDirect3DDevice9_BeginScene(device);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4437 if(SUCCEEDED(hr))
4439 float quad1[] = {
4440 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4441 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4442 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4443 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4445 float quad2[] = {
4446 -1.0, 0.0, 0.1,
4447 -1.0, 1.0, 0.1,
4448 0.0, 0.0, 0.1,
4449 0.0, 1.0, 0.1,
4451 float quad3[] = {
4452 0.0, 0.0, 0.1, 1.0,
4453 0.0, 1.0, 0.1, 1.0,
4454 1.0, 0.0, 0.1, 1.0,
4455 1.0, 1.0, 0.1, 1.0
4457 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4458 0.0, 0.0, 0.0, 0.0,
4459 0.0, 0.0, 0.0, 0.0,
4460 0.0, 1.0, 0.0, 0.0};
4461 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4462 1.0, 0.0, 0.0, 0.0,
4463 0.0, 1.0, 0.0, 0.0,
4464 0.0, 0.0, 1.0, 0.0};
4465 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4466 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4468 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4469 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4470 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4471 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4472 * 4th *input* coordinate.
4474 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4475 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4476 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4477 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4479 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4481 /* None passed */
4482 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4483 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4484 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4485 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4487 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4489 /* 4 used, 1 passed */
4490 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4491 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4492 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4493 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4495 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4497 hr = IDirect3DDevice9_EndScene(device);
4498 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4500 color = getPixelColor(device, 160, 360);
4501 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4502 color = getPixelColor(device, 160, 120);
4503 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4504 color = getPixelColor(device, 480, 120);
4505 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4506 /* Quad4: unused */
4508 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4509 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4511 IDirect3DVolumeTexture9_Release(volume);
4513 out:
4514 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4515 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4516 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4517 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4518 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4519 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4520 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4521 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4522 IDirect3DVertexDeclaration9_Release(decl);
4523 IDirect3DVertexDeclaration9_Release(decl2);
4524 IDirect3DVertexDeclaration9_Release(decl3);
4525 IDirect3DVertexDeclaration9_Release(decl4);
4528 static void texdepth_test(IDirect3DDevice9 *device)
4530 IDirect3DPixelShader9 *shader;
4531 HRESULT hr;
4532 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4533 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4534 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4535 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4536 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4537 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4538 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4539 DWORD shader_code[] = {
4540 0xffff0104, /* ps_1_4 */
4541 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4542 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4543 0x0000fffd, /* phase */
4544 0x00000057, 0x800f0005, /* texdepth r5 */
4545 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4546 0x0000ffff /* end */
4548 DWORD color;
4549 float vertex[] = {
4550 -1.0, -1.0, 0.0,
4551 1.0, -1.0, 1.0,
4552 -1.0, 1.0, 0.0,
4553 1.0, 1.0, 1.0
4556 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4562 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4564 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4566 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4567 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4568 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4570 /* Fill the depth buffer with a gradient */
4571 hr = IDirect3DDevice9_BeginScene(device);
4572 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4573 if(SUCCEEDED(hr))
4575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4576 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4577 hr = IDirect3DDevice9_EndScene(device);
4578 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4581 /* Now perform the actual tests. Same geometry, but with the shader */
4582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4583 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4585 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4586 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4587 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4589 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4590 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4591 hr = IDirect3DDevice9_BeginScene(device);
4592 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4593 if(SUCCEEDED(hr))
4595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4596 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4598 hr = IDirect3DDevice9_EndScene(device);
4599 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4602 color = getPixelColor(device, 158, 240);
4603 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4604 color = getPixelColor(device, 162, 240);
4605 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4607 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4608 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4610 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4611 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4613 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4614 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4615 hr = IDirect3DDevice9_BeginScene(device);
4616 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4617 if(SUCCEEDED(hr))
4619 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4620 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4622 hr = IDirect3DDevice9_EndScene(device);
4623 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4626 color = getPixelColor(device, 318, 240);
4627 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4628 color = getPixelColor(device, 322, 240);
4629 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4631 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4632 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4634 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4635 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4637 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4639 hr = IDirect3DDevice9_BeginScene(device);
4640 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4641 if(SUCCEEDED(hr))
4643 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4644 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4646 hr = IDirect3DDevice9_EndScene(device);
4647 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4650 color = getPixelColor(device, 1, 240);
4651 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4653 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4654 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4656 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4657 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4659 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4660 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4661 hr = IDirect3DDevice9_BeginScene(device);
4662 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4663 if(SUCCEEDED(hr))
4665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4666 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4668 hr = IDirect3DDevice9_EndScene(device);
4669 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4671 color = getPixelColor(device, 318, 240);
4672 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4673 color = getPixelColor(device, 322, 240);
4674 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4676 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4680 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4682 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4683 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4684 hr = IDirect3DDevice9_BeginScene(device);
4685 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4686 if(SUCCEEDED(hr))
4688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4689 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4691 hr = IDirect3DDevice9_EndScene(device);
4692 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4695 color = getPixelColor(device, 1, 240);
4696 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4698 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4699 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4702 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4704 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4705 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4706 hr = IDirect3DDevice9_BeginScene(device);
4707 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4708 if(SUCCEEDED(hr))
4710 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4711 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4713 hr = IDirect3DDevice9_EndScene(device);
4714 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4717 color = getPixelColor(device, 638, 240);
4718 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4720 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4721 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4723 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4724 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4726 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4727 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4728 hr = IDirect3DDevice9_BeginScene(device);
4729 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4730 if(SUCCEEDED(hr))
4732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4733 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4735 hr = IDirect3DDevice9_EndScene(device);
4736 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4739 color = getPixelColor(device, 638, 240);
4740 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4743 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4745 /* Cleanup */
4746 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4747 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4748 IDirect3DPixelShader9_Release(shader);
4750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4753 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4756 static void texkill_test(IDirect3DDevice9 *device)
4758 IDirect3DPixelShader9 *shader;
4759 HRESULT hr;
4760 DWORD color;
4762 const float vertex[] = {
4763 /* bottom top right left */
4764 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4765 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4766 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4767 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4770 DWORD shader_code_11[] = {
4771 0xffff0101, /* ps_1_1 */
4772 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4773 0x00000041, 0xb00f0000, /* texkill t0 */
4774 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4775 0x0000ffff /* end */
4777 DWORD shader_code_20[] = {
4778 0xffff0200, /* ps_2_0 */
4779 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4780 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4781 0x01000041, 0xb00f0000, /* texkill t0 */
4782 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4783 0x0000ffff /* end */
4786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4787 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4788 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4789 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4791 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4792 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader 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_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4800 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4801 hr = IDirect3DDevice9_EndScene(device);
4802 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4804 color = getPixelColor(device, 63, 46);
4805 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4806 color = getPixelColor(device, 66, 46);
4807 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4808 color = getPixelColor(device, 63, 49);
4809 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4810 color = getPixelColor(device, 66, 49);
4811 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4813 color = getPixelColor(device, 578, 46);
4814 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4815 color = getPixelColor(device, 575, 46);
4816 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4817 color = getPixelColor(device, 578, 49);
4818 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4819 color = getPixelColor(device, 575, 49);
4820 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4822 color = getPixelColor(device, 63, 430);
4823 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4824 color = getPixelColor(device, 63, 433);
4825 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4826 color = getPixelColor(device, 66, 433);
4827 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4828 color = getPixelColor(device, 66, 430);
4829 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4831 color = getPixelColor(device, 578, 430);
4832 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4833 color = getPixelColor(device, 578, 433);
4834 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4835 color = getPixelColor(device, 575, 433);
4836 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4837 color = getPixelColor(device, 575, 430);
4838 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4841 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4843 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4845 IDirect3DPixelShader9_Release(shader);
4847 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4849 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4850 if(FAILED(hr)) {
4851 skip("Failed to create 2.0 test shader, most likely not supported\n");
4852 return;
4855 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4857 hr = IDirect3DDevice9_BeginScene(device);
4858 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4859 if(SUCCEEDED(hr))
4861 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4862 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4863 hr = IDirect3DDevice9_EndScene(device);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4867 color = getPixelColor(device, 63, 46);
4868 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4869 color = getPixelColor(device, 66, 46);
4870 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4871 color = getPixelColor(device, 63, 49);
4872 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4873 color = getPixelColor(device, 66, 49);
4874 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4876 color = getPixelColor(device, 578, 46);
4877 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4878 color = getPixelColor(device, 575, 46);
4879 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4880 color = getPixelColor(device, 578, 49);
4881 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4882 color = getPixelColor(device, 575, 49);
4883 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4885 color = getPixelColor(device, 63, 430);
4886 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4887 color = getPixelColor(device, 63, 433);
4888 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4889 color = getPixelColor(device, 66, 433);
4890 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4891 color = getPixelColor(device, 66, 430);
4892 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4894 color = getPixelColor(device, 578, 430);
4895 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4896 color = getPixelColor(device, 578, 433);
4897 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4898 color = getPixelColor(device, 575, 433);
4899 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4900 color = getPixelColor(device, 575, 430);
4901 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4903 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4904 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4906 /* Cleanup */
4907 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4908 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4909 IDirect3DPixelShader9_Release(shader);
4912 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4914 IDirect3D9 *d3d9;
4915 HRESULT hr;
4916 IDirect3DTexture9 *texture;
4917 IDirect3DPixelShader9 *shader;
4918 IDirect3DPixelShader9 *shader2;
4919 D3DLOCKED_RECT lr;
4920 DWORD color;
4921 DWORD shader_code[] = {
4922 0xffff0101, /* ps_1_1 */
4923 0x00000042, 0xb00f0000, /* tex t0 */
4924 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4925 0x0000ffff /* end */
4927 DWORD shader_code2[] = {
4928 0xffff0101, /* ps_1_1 */
4929 0x00000042, 0xb00f0000, /* tex t0 */
4930 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4931 0x0000ffff /* end */
4934 float quad[] = {
4935 -1.0, -1.0, 0.1, 0.5, 0.5,
4936 1.0, -1.0, 0.1, 0.5, 0.5,
4937 -1.0, 1.0, 0.1, 0.5, 0.5,
4938 1.0, 1.0, 0.1, 0.5, 0.5,
4941 memset(&lr, 0, sizeof(lr));
4942 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4943 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4944 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4945 IDirect3D9_Release(d3d9);
4946 if(FAILED(hr)) {
4947 skip("No D3DFMT_X8L8V8U8 support\n");
4948 return;
4951 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4952 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4954 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4956 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4957 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4958 *((DWORD *) lr.pBits) = 0x11ca3141;
4959 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4960 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4962 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4963 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4964 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4967 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4968 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4969 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4970 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4971 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4972 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4974 hr = IDirect3DDevice9_BeginScene(device);
4975 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4976 if(SUCCEEDED(hr))
4978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4979 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4981 hr = IDirect3DDevice9_EndScene(device);
4982 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4984 color = getPixelColor(device, 578, 430);
4985 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4986 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4987 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4990 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4992 hr = IDirect3DDevice9_BeginScene(device);
4993 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4994 if(SUCCEEDED(hr))
4996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4997 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4999 hr = IDirect3DDevice9_EndScene(device);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5002 color = getPixelColor(device, 578, 430);
5003 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5004 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5005 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5007 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5008 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5009 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5010 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5011 IDirect3DPixelShader9_Release(shader);
5012 IDirect3DPixelShader9_Release(shader2);
5013 IDirect3DTexture9_Release(texture);
5016 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5018 HRESULT hr;
5019 IDirect3D9 *d3d;
5020 IDirect3DTexture9 *texture = NULL;
5021 IDirect3DSurface9 *surface;
5022 DWORD color;
5023 const RECT r1 = {256, 256, 512, 512};
5024 const RECT r2 = {512, 256, 768, 512};
5025 const RECT r3 = {256, 512, 512, 768};
5026 const RECT r4 = {512, 512, 768, 768};
5027 unsigned int x, y;
5028 D3DLOCKED_RECT lr;
5029 memset(&lr, 0, sizeof(lr));
5031 IDirect3DDevice9_GetDirect3D(device, &d3d);
5032 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5033 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5034 skip("No autogenmipmap support\n");
5035 IDirect3D9_Release(d3d);
5036 return;
5038 IDirect3D9_Release(d3d);
5040 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5041 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5043 /* Make the mipmap big, so that a smaller mipmap is used
5045 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5046 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5047 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5049 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5050 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5051 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5052 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5053 for(y = 0; y < 1024; y++) {
5054 for(x = 0; x < 1024; x++) {
5055 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5056 POINT pt;
5058 pt.x = x;
5059 pt.y = y;
5060 if(PtInRect(&r1, pt)) {
5061 *dst = 0xffff0000;
5062 } else if(PtInRect(&r2, pt)) {
5063 *dst = 0xff00ff00;
5064 } else if(PtInRect(&r3, pt)) {
5065 *dst = 0xff0000ff;
5066 } else if(PtInRect(&r4, pt)) {
5067 *dst = 0xff000000;
5068 } else {
5069 *dst = 0xffffffff;
5073 hr = IDirect3DSurface9_UnlockRect(surface);
5074 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5075 IDirect3DSurface9_Release(surface);
5077 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5078 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5079 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5080 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5082 hr = IDirect3DDevice9_BeginScene(device);
5083 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5084 if(SUCCEEDED(hr)) {
5085 const float quad[] = {
5086 -0.5, -0.5, 0.1, 0.0, 0.0,
5087 -0.5, 0.5, 0.1, 0.0, 1.0,
5088 0.5, -0.5, 0.1, 1.0, 0.0,
5089 0.5, 0.5, 0.1, 1.0, 1.0
5092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5093 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5094 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5095 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5096 hr = IDirect3DDevice9_EndScene(device);
5097 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5099 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5100 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5101 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5102 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5103 IDirect3DTexture9_Release(texture);
5105 color = getPixelColor(device, 200, 200);
5106 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5107 color = getPixelColor(device, 280, 200);
5108 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5109 color = getPixelColor(device, 360, 200);
5110 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5111 color = getPixelColor(device, 440, 200);
5112 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5113 color = getPixelColor(device, 200, 270);
5114 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5115 color = getPixelColor(device, 280, 270);
5116 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5117 color = getPixelColor(device, 360, 270);
5118 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5119 color = getPixelColor(device, 440, 270);
5120 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5121 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5122 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5125 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5127 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5128 IDirect3DVertexDeclaration9 *decl;
5129 HRESULT hr;
5130 DWORD color;
5131 DWORD shader_code_11[] = {
5132 0xfffe0101, /* vs_1_1 */
5133 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5134 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5135 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5136 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5137 0x0000ffff /* end */
5139 DWORD shader_code_11_2[] = {
5140 0xfffe0101, /* vs_1_1 */
5141 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5142 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5143 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5144 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5145 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5146 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5147 0x0000ffff /* end */
5149 DWORD shader_code_20[] = {
5150 0xfffe0200, /* vs_2_0 */
5151 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5152 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5153 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5154 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5155 0x0000ffff /* end */
5157 DWORD shader_code_20_2[] = {
5158 0xfffe0200, /* vs_2_0 */
5159 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5160 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5161 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5162 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5163 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5164 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5165 0x0000ffff /* end */
5167 static const D3DVERTEXELEMENT9 decl_elements[] = {
5168 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5169 D3DDECL_END()
5171 float quad1[] = {
5172 -1.0, -1.0, 0.1,
5173 0.0, -1.0, 0.1,
5174 -1.0, 0.0, 0.1,
5175 0.0, 0.0, 0.1
5177 float quad2[] = {
5178 0.0, -1.0, 0.1,
5179 1.0, -1.0, 0.1,
5180 0.0, 0.0, 0.1,
5181 1.0, 0.0, 0.1
5183 float quad3[] = {
5184 0.0, 0.0, 0.1,
5185 1.0, 0.0, 0.1,
5186 0.0, 1.0, 0.1,
5187 1.0, 1.0, 0.1
5189 float quad4[] = {
5190 -1.0, 0.0, 0.1,
5191 0.0, 0.0, 0.1,
5192 -1.0, 1.0, 0.1,
5193 0.0, 1.0, 0.1
5195 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5196 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5198 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5199 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5201 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5203 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5205 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5206 if(FAILED(hr)) shader_20 = NULL;
5207 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5208 if(FAILED(hr)) shader_20_2 = NULL;
5209 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5210 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5212 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5213 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5214 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5216 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5217 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5219 hr = IDirect3DDevice9_BeginScene(device);
5220 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5221 if(SUCCEEDED(hr))
5223 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5224 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5226 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5228 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5231 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5233 if(shader_20) {
5234 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5235 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5237 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5240 if(shader_20_2) {
5241 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5244 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5247 hr = IDirect3DDevice9_EndScene(device);
5248 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5251 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5253 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5254 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5256 color = getPixelColor(device, 160, 360);
5257 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5258 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5259 color = getPixelColor(device, 480, 360);
5260 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5261 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5262 if(shader_20) {
5263 color = getPixelColor(device, 480, 120);
5264 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5265 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5267 if(shader_20_2) {
5268 color = getPixelColor(device, 160, 120);
5269 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5270 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5272 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5273 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5275 IDirect3DVertexDeclaration9_Release(decl);
5276 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5277 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5278 IDirect3DVertexShader9_Release(shader_11_2);
5279 IDirect3DVertexShader9_Release(shader_11);
5282 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5284 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5285 HRESULT hr;
5286 DWORD color;
5287 DWORD shader_code_11[] = {
5288 0xffff0101, /* ps_1_1 */
5289 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5290 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5291 0x0000ffff /* end */
5293 DWORD shader_code_12[] = {
5294 0xffff0102, /* ps_1_2 */
5295 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5296 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5297 0x0000ffff /* end */
5299 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5300 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5301 * During development of this test, 1.3 shaders were verified too
5303 DWORD shader_code_14[] = {
5304 0xffff0104, /* ps_1_4 */
5305 /* Try to make one constant local. It gets clamped too, although the binary contains
5306 * the bigger numbers
5308 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5309 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5310 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5311 0x0000ffff /* end */
5313 DWORD shader_code_20[] = {
5314 0xffff0200, /* ps_2_0 */
5315 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5316 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5317 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5318 0x0000ffff /* end */
5320 float quad1[] = {
5321 -1.0, -1.0, 0.1,
5322 0.0, -1.0, 0.1,
5323 -1.0, 0.0, 0.1,
5324 0.0, 0.0, 0.1
5326 float quad2[] = {
5327 0.0, -1.0, 0.1,
5328 1.0, -1.0, 0.1,
5329 0.0, 0.0, 0.1,
5330 1.0, 0.0, 0.1
5332 float quad3[] = {
5333 0.0, 0.0, 0.1,
5334 1.0, 0.0, 0.1,
5335 0.0, 1.0, 0.1,
5336 1.0, 1.0, 0.1
5338 float quad4[] = {
5339 -1.0, 0.0, 0.1,
5340 0.0, 0.0, 0.1,
5341 -1.0, 1.0, 0.1,
5342 0.0, 1.0, 0.1
5344 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5345 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5347 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5350 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5352 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5353 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5354 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5355 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5356 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5357 if(FAILED(hr)) shader_20 = NULL;
5359 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5360 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5361 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5363 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5364 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5366 hr = IDirect3DDevice9_BeginScene(device);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5368 if(SUCCEEDED(hr))
5370 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5371 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5373 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5375 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5376 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5378 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5380 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5381 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5383 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5385 if(shader_20) {
5386 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5387 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5389 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5392 hr = IDirect3DDevice9_EndScene(device);
5393 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5395 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5396 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5398 color = getPixelColor(device, 160, 360);
5399 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5400 "quad 1 has color %08x, expected 0x00808000\n", color);
5401 color = getPixelColor(device, 480, 360);
5402 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5403 "quad 2 has color %08x, expected 0x00808000\n", color);
5404 color = getPixelColor(device, 480, 120);
5405 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5406 "quad 3 has color %08x, expected 0x00808000\n", color);
5407 if(shader_20) {
5408 color = getPixelColor(device, 160, 120);
5409 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5410 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5412 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5413 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5415 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5416 IDirect3DPixelShader9_Release(shader_14);
5417 IDirect3DPixelShader9_Release(shader_12);
5418 IDirect3DPixelShader9_Release(shader_11);
5421 static void dp2add_ps_test(IDirect3DDevice9 *device)
5423 IDirect3DPixelShader9 *shader_dp2add = NULL;
5424 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5425 HRESULT hr;
5426 DWORD color;
5428 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5429 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5430 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5431 * r0 first.
5432 * The result here for the r,g,b components should be roughly 0.5:
5433 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5434 static const DWORD shader_code_dp2add[] = {
5435 0xffff0200, /* ps_2_0 */
5436 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5438 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5439 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5441 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5442 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5443 0x0000ffff /* end */
5446 /* Test the _sat modifier, too. Result here should be:
5447 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5448 * _SAT: ==> 1.0
5449 * ADD: (1.0 + -0.5) = 0.5
5451 static const DWORD shader_code_dp2add_sat[] = {
5452 0xffff0200, /* ps_2_0 */
5453 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5455 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5456 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5457 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5459 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5460 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5461 0x0000ffff /* end */
5464 const float quad[] = {
5465 -1.0, -1.0, 0.1,
5466 1.0, -1.0, 0.1,
5467 -1.0, 1.0, 0.1,
5468 1.0, 1.0, 0.1
5472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5473 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5475 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5476 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5478 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5479 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5481 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5484 if (shader_dp2add) {
5486 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5487 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5489 hr = IDirect3DDevice9_BeginScene(device);
5490 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5491 if(SUCCEEDED(hr))
5493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5494 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5496 hr = IDirect3DDevice9_EndScene(device);
5497 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5500 color = getPixelColor(device, 360, 240);
5501 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5502 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5504 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5505 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5507 IDirect3DPixelShader9_Release(shader_dp2add);
5508 } else {
5509 skip("dp2add shader creation failed\n");
5512 if (shader_dp2add_sat) {
5514 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5515 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5517 hr = IDirect3DDevice9_BeginScene(device);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5519 if(SUCCEEDED(hr))
5521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5522 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5524 hr = IDirect3DDevice9_EndScene(device);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5528 color = getPixelColor(device, 360, 240);
5529 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5530 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5532 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5533 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5535 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5536 } else {
5537 skip("dp2add shader creation failed\n");
5540 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5541 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5544 static void cnd_test(IDirect3DDevice9 *device)
5546 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5547 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5548 HRESULT hr;
5549 DWORD color;
5550 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5551 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5552 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5554 DWORD shader_code_11[] = {
5555 0xffff0101, /* ps_1_1 */
5556 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5557 0x00000040, 0xb00f0000, /* texcoord t0 */
5558 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5559 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5560 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5561 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5562 0x0000ffff /* end */
5564 DWORD shader_code_12[] = {
5565 0xffff0102, /* ps_1_2 */
5566 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5567 0x00000040, 0xb00f0000, /* texcoord t0 */
5568 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5569 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5570 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5571 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5572 0x0000ffff /* end */
5574 DWORD shader_code_13[] = {
5575 0xffff0103, /* ps_1_3 */
5576 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5577 0x00000040, 0xb00f0000, /* texcoord t0 */
5578 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5579 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5580 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5581 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5582 0x0000ffff /* end */
5584 DWORD shader_code_14[] = {
5585 0xffff0104, /* ps_1_3 */
5586 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5587 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5588 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5589 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5590 0x0000ffff /* end */
5593 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5594 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5595 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5596 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5597 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5598 * well enough.
5600 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5601 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5602 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5603 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5605 DWORD shader_code_11_coissue[] = {
5606 0xffff0101, /* ps_1_1 */
5607 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5608 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5609 0x00000040, 0xb00f0000, /* texcoord t0 */
5610 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5611 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5612 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5613 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5614 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5615 /* 0x40000000 = D3DSI_COISSUE */
5616 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5617 0x0000ffff /* end */
5619 DWORD shader_code_12_coissue[] = {
5620 0xffff0102, /* ps_1_2 */
5621 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5622 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5623 0x00000040, 0xb00f0000, /* texcoord t0 */
5624 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5625 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5626 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5627 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5628 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5629 /* 0x40000000 = D3DSI_COISSUE */
5630 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5631 0x0000ffff /* end */
5633 DWORD shader_code_13_coissue[] = {
5634 0xffff0103, /* ps_1_3 */
5635 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5636 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5637 0x00000040, 0xb00f0000, /* texcoord t0 */
5638 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5639 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5640 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5641 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5642 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5643 /* 0x40000000 = D3DSI_COISSUE */
5644 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5645 0x0000ffff /* end */
5647 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5648 * compare against 0.5
5650 DWORD shader_code_14_coissue[] = {
5651 0xffff0104, /* ps_1_4 */
5652 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5653 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5654 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5655 /* 0x40000000 = D3DSI_COISSUE */
5656 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5657 0x0000ffff /* end */
5659 float quad1[] = {
5660 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5661 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5662 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5663 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5665 float quad2[] = {
5666 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5667 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5668 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5669 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5671 float quad3[] = {
5672 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5673 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5674 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5675 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5677 float quad4[] = {
5678 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5679 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5680 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5681 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5683 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5684 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5685 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5686 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5689 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5691 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5692 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5693 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5694 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5695 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5696 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5697 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5698 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5699 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5700 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5701 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5702 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5703 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5704 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5705 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5706 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5708 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5709 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5710 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5711 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5712 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5713 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5715 hr = IDirect3DDevice9_BeginScene(device);
5716 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5717 if(SUCCEEDED(hr))
5719 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5722 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5724 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5725 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5727 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5729 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5730 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5732 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5734 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5735 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5737 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5739 hr = IDirect3DDevice9_EndScene(device);
5740 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5743 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5744 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5746 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5747 color = getPixelColor(device, 158, 118);
5748 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5749 color = getPixelColor(device, 162, 118);
5750 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5751 color = getPixelColor(device, 158, 122);
5752 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5753 color = getPixelColor(device, 162, 122);
5754 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5756 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5757 color = getPixelColor(device, 158, 358);
5758 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5759 color = getPixelColor(device, 162, 358);
5760 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5761 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5762 color = getPixelColor(device, 158, 362);
5763 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5764 color = getPixelColor(device, 162, 362);
5765 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5766 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5768 /* 1.2 shader */
5769 color = getPixelColor(device, 478, 358);
5770 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5771 color = getPixelColor(device, 482, 358);
5772 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5773 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5774 color = getPixelColor(device, 478, 362);
5775 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5776 color = getPixelColor(device, 482, 362);
5777 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5778 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5780 /* 1.3 shader */
5781 color = getPixelColor(device, 478, 118);
5782 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5783 color = getPixelColor(device, 482, 118);
5784 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5785 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5786 color = getPixelColor(device, 478, 122);
5787 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5788 color = getPixelColor(device, 482, 122);
5789 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5790 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5793 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5796 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5797 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5798 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5799 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5802 hr = IDirect3DDevice9_BeginScene(device);
5803 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5804 if(SUCCEEDED(hr))
5806 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5807 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5809 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5811 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5814 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5816 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5817 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5819 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5821 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5822 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5824 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5826 hr = IDirect3DDevice9_EndScene(device);
5827 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5830 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5831 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5833 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5834 * that we swapped the values in c1 and c2 to make the other tests return some color
5836 color = getPixelColor(device, 158, 118);
5837 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5838 color = getPixelColor(device, 162, 118);
5839 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5840 color = getPixelColor(device, 158, 122);
5841 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5842 color = getPixelColor(device, 162, 122);
5843 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5845 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5846 * (The Win7 nvidia driver always selects c2)
5848 color = getPixelColor(device, 158, 358);
5849 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5850 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5851 color = getPixelColor(device, 162, 358);
5852 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5853 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5854 color = getPixelColor(device, 158, 362);
5855 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5856 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5857 color = getPixelColor(device, 162, 362);
5858 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5859 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5861 /* 1.2 shader */
5862 color = getPixelColor(device, 478, 358);
5863 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5864 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5865 color = getPixelColor(device, 482, 358);
5866 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5867 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5868 color = getPixelColor(device, 478, 362);
5869 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5870 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5871 color = getPixelColor(device, 482, 362);
5872 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5873 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5875 /* 1.3 shader */
5876 color = getPixelColor(device, 478, 118);
5877 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5878 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5879 color = getPixelColor(device, 482, 118);
5880 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5881 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5882 color = getPixelColor(device, 478, 122);
5883 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5884 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5885 color = getPixelColor(device, 482, 122);
5886 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5887 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5889 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5890 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5892 IDirect3DPixelShader9_Release(shader_14_coissue);
5893 IDirect3DPixelShader9_Release(shader_13_coissue);
5894 IDirect3DPixelShader9_Release(shader_12_coissue);
5895 IDirect3DPixelShader9_Release(shader_11_coissue);
5896 IDirect3DPixelShader9_Release(shader_14);
5897 IDirect3DPixelShader9_Release(shader_13);
5898 IDirect3DPixelShader9_Release(shader_12);
5899 IDirect3DPixelShader9_Release(shader_11);
5902 static void nested_loop_test(IDirect3DDevice9 *device) {
5903 const DWORD shader_code[] = {
5904 0xffff0300, /* ps_3_0 */
5905 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5906 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5907 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5908 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5909 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5910 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5911 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5912 0x0000001d, /* endloop */
5913 0x0000001d, /* endloop */
5914 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5915 0x0000ffff /* end */
5917 const DWORD vshader_code[] = {
5918 0xfffe0300, /* vs_3_0 */
5919 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5920 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5921 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5922 0x0000ffff /* end */
5924 IDirect3DPixelShader9 *shader;
5925 IDirect3DVertexShader9 *vshader;
5926 HRESULT hr;
5927 DWORD color;
5928 const float quad[] = {
5929 -1.0, -1.0, 0.1,
5930 1.0, -1.0, 0.1,
5931 -1.0, 1.0, 0.1,
5932 1.0, 1.0, 0.1
5935 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5936 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5937 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5938 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5939 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5940 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5941 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5942 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5944 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5946 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5948 hr = IDirect3DDevice9_BeginScene(device);
5949 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5950 if(SUCCEEDED(hr))
5952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5953 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5954 hr = IDirect3DDevice9_EndScene(device);
5955 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5958 color = getPixelColor(device, 360, 240);
5959 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5960 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5963 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5965 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5966 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5967 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5968 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5969 IDirect3DPixelShader9_Release(shader);
5970 IDirect3DVertexShader9_Release(vshader);
5973 struct varying_test_struct
5975 const DWORD *shader_code;
5976 IDirect3DPixelShader9 *shader;
5977 DWORD color, color_rhw;
5978 const char *name;
5979 BOOL todo, todo_rhw;
5982 struct hugeVertex
5984 float pos_x, pos_y, pos_z, rhw;
5985 float weight_1, weight_2, weight_3, weight_4;
5986 float index_1, index_2, index_3, index_4;
5987 float normal_1, normal_2, normal_3, normal_4;
5988 float fog_1, fog_2, fog_3, fog_4;
5989 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5990 float tangent_1, tangent_2, tangent_3, tangent_4;
5991 float binormal_1, binormal_2, binormal_3, binormal_4;
5992 float depth_1, depth_2, depth_3, depth_4;
5993 DWORD diffuse, specular;
5996 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5997 /* dcl_position: fails to compile */
5998 const DWORD blendweight_code[] = {
5999 0xffff0300, /* ps_3_0 */
6000 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6001 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6002 0x0000ffff /* end */
6004 const DWORD blendindices_code[] = {
6005 0xffff0300, /* ps_3_0 */
6006 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6007 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6008 0x0000ffff /* end */
6010 const DWORD normal_code[] = {
6011 0xffff0300, /* ps_3_0 */
6012 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6013 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6014 0x0000ffff /* end */
6016 /* psize: fails? */
6017 const DWORD texcoord0_code[] = {
6018 0xffff0300, /* ps_3_0 */
6019 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6020 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6021 0x0000ffff /* end */
6023 const DWORD tangent_code[] = {
6024 0xffff0300, /* ps_3_0 */
6025 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6026 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6027 0x0000ffff /* end */
6029 const DWORD binormal_code[] = {
6030 0xffff0300, /* ps_3_0 */
6031 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6032 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6033 0x0000ffff /* end */
6035 /* tessfactor: fails */
6036 /* positiont: fails */
6037 const DWORD color_code[] = {
6038 0xffff0300, /* ps_3_0 */
6039 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6040 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6041 0x0000ffff /* end */
6043 const DWORD fog_code[] = {
6044 0xffff0300, /* ps_3_0 */
6045 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
6046 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6047 0x0000ffff /* end */
6049 const DWORD depth_code[] = {
6050 0xffff0300, /* ps_3_0 */
6051 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
6052 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6053 0x0000ffff /* end */
6055 const DWORD specular_code[] = {
6056 0xffff0300, /* ps_3_0 */
6057 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
6058 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6059 0x0000ffff /* end */
6061 /* sample: fails */
6063 struct varying_test_struct tests[] = {
6064 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
6065 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
6066 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
6067 /* Why does dx not forward the texcoord? */
6068 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
6069 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
6070 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
6071 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
6072 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
6073 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
6074 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
6076 /* Declare a monster vertex type :-) */
6077 static const D3DVERTEXELEMENT9 decl_elements[] = {
6078 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6079 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
6080 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
6081 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
6082 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
6083 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6084 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
6085 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
6086 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
6087 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6088 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
6089 D3DDECL_END()
6091 struct hugeVertex data[4] = {
6093 -1.0, -1.0, 0.1, 1.0,
6094 0.1, 0.1, 0.1, 0.1,
6095 0.2, 0.2, 0.2, 0.2,
6096 0.3, 0.3, 0.3, 0.3,
6097 0.4, 0.4, 0.4, 0.4,
6098 0.50, 0.55, 0.55, 0.55,
6099 0.6, 0.6, 0.6, 0.7,
6100 0.7, 0.7, 0.7, 0.6,
6101 0.8, 0.8, 0.8, 0.8,
6102 0xe6e6e6e6, /* 0.9 * 256 */
6103 0x224488ff /* Nothing special */
6106 1.0, -1.0, 0.1, 1.0,
6107 0.1, 0.1, 0.1, 0.1,
6108 0.2, 0.2, 0.2, 0.2,
6109 0.3, 0.3, 0.3, 0.3,
6110 0.4, 0.4, 0.4, 0.4,
6111 0.50, 0.55, 0.55, 0.55,
6112 0.6, 0.6, 0.6, 0.7,
6113 0.7, 0.7, 0.7, 0.6,
6114 0.8, 0.8, 0.8, 0.8,
6115 0xe6e6e6e6, /* 0.9 * 256 */
6116 0x224488ff /* Nothing special */
6119 -1.0, 1.0, 0.1, 1.0,
6120 0.1, 0.1, 0.1, 0.1,
6121 0.2, 0.2, 0.2, 0.2,
6122 0.3, 0.3, 0.3, 0.3,
6123 0.4, 0.4, 0.4, 0.4,
6124 0.50, 0.55, 0.55, 0.55,
6125 0.6, 0.6, 0.6, 0.7,
6126 0.7, 0.7, 0.7, 0.6,
6127 0.8, 0.8, 0.8, 0.8,
6128 0xe6e6e6e6, /* 0.9 * 256 */
6129 0x224488ff /* Nothing special */
6132 1.0, 1.0, 0.1, 1.0,
6133 0.1, 0.1, 0.1, 0.1,
6134 0.2, 0.2, 0.2, 0.2,
6135 0.3, 0.3, 0.3, 0.3,
6136 0.4, 0.4, 0.4, 0.4,
6137 0.50, 0.55, 0.55, 0.55,
6138 0.6, 0.6, 0.6, 0.7,
6139 0.7, 0.7, 0.7, 0.6,
6140 0.8, 0.8, 0.8, 0.8,
6141 0xe6e6e6e6, /* 0.9 * 256 */
6142 0x224488ff /* Nothing special */
6145 struct hugeVertex data2[4];
6146 IDirect3DVertexDeclaration9 *decl;
6147 HRESULT hr;
6148 unsigned int i;
6149 DWORD color, r, g, b, r_e, g_e, b_e;
6151 memcpy(data2, data, sizeof(data2));
6152 data2[0].pos_x = 0; data2[0].pos_y = 0;
6153 data2[1].pos_x = 640; data2[1].pos_y = 0;
6154 data2[2].pos_x = 0; data2[2].pos_y = 480;
6155 data2[3].pos_x = 640; data2[3].pos_y = 480;
6157 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6158 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6159 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6160 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6162 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6164 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6165 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6166 tests[i].name, hr);
6169 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6170 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6171 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6173 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6176 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6177 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6179 hr = IDirect3DDevice9_BeginScene(device);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6181 if(SUCCEEDED(hr))
6183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6184 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6185 hr = IDirect3DDevice9_EndScene(device);
6186 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6189 color = getPixelColor(device, 360, 240);
6190 r = color & 0x00ff0000 >> 16;
6191 g = color & 0x0000ff00 >> 8;
6192 b = color & 0x000000ff;
6193 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6194 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
6195 b_e = tests[i].color_rhw & 0x000000ff;
6197 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6198 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6200 if(tests[i].todo_rhw) {
6201 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6202 * pipeline
6204 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6205 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6206 tests[i].name, color, tests[i].color_rhw);
6207 } else {
6208 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6209 "Test %s returned color 0x%08x, expected 0x%08x\n",
6210 tests[i].name, color, tests[i].color_rhw);
6214 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6216 IDirect3DPixelShader9_Release(tests[i].shader);
6219 IDirect3DVertexDeclaration9_Release(decl);
6222 static void test_compare_instructions(IDirect3DDevice9 *device)
6224 DWORD shader_sge_vec_code[] = {
6225 0xfffe0101, /* vs_1_1 */
6226 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6227 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6228 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6229 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6230 0x0000ffff /* end */
6232 DWORD shader_slt_vec_code[] = {
6233 0xfffe0101, /* vs_1_1 */
6234 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6235 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6236 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6237 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6238 0x0000ffff /* end */
6240 DWORD shader_sge_scalar_code[] = {
6241 0xfffe0101, /* vs_1_1 */
6242 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6243 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6244 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6245 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6246 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6247 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6248 0x0000ffff /* end */
6250 DWORD shader_slt_scalar_code[] = {
6251 0xfffe0101, /* vs_1_1 */
6252 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6253 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6254 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6255 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6256 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6257 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6258 0x0000ffff /* end */
6260 IDirect3DVertexShader9 *shader_sge_vec;
6261 IDirect3DVertexShader9 *shader_slt_vec;
6262 IDirect3DVertexShader9 *shader_sge_scalar;
6263 IDirect3DVertexShader9 *shader_slt_scalar;
6264 HRESULT hr, color;
6265 float quad1[] = {
6266 -1.0, -1.0, 0.1,
6267 0.0, -1.0, 0.1,
6268 -1.0, 0.0, 0.1,
6269 0.0, 0.0, 0.1
6271 float quad2[] = {
6272 0.0, -1.0, 0.1,
6273 1.0, -1.0, 0.1,
6274 0.0, 0.0, 0.1,
6275 1.0, 0.0, 0.1
6277 float quad3[] = {
6278 -1.0, 0.0, 0.1,
6279 0.0, 0.0, 0.1,
6280 -1.0, 1.0, 0.1,
6281 0.0, 1.0, 0.1
6283 float quad4[] = {
6284 0.0, 0.0, 0.1,
6285 1.0, 0.0, 0.1,
6286 0.0, 1.0, 0.1,
6287 1.0, 1.0, 0.1
6289 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6290 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6292 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6293 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6295 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6296 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6297 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6299 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6301 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6302 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6303 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6304 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6305 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6306 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6307 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6308 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6310 hr = IDirect3DDevice9_BeginScene(device);
6311 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6312 if(SUCCEEDED(hr))
6314 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6317 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6319 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6324 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6325 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6327 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6329 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6330 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6332 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6333 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6335 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6337 hr = IDirect3DDevice9_EndScene(device);
6338 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6341 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6342 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6344 color = getPixelColor(device, 160, 360);
6345 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6346 color = getPixelColor(device, 480, 360);
6347 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6348 color = getPixelColor(device, 160, 120);
6349 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6350 color = getPixelColor(device, 480, 160);
6351 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6353 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6356 IDirect3DVertexShader9_Release(shader_sge_vec);
6357 IDirect3DVertexShader9_Release(shader_slt_vec);
6358 IDirect3DVertexShader9_Release(shader_sge_scalar);
6359 IDirect3DVertexShader9_Release(shader_slt_scalar);
6362 static void test_vshader_input(IDirect3DDevice9 *device)
6364 static const DWORD swapped_shader_code_3[] =
6366 0xfffe0300, /* vs_3_0 */
6367 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6368 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6369 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6370 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6371 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6372 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6373 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6374 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6375 0x0000ffff /* end */
6377 static const DWORD swapped_shader_code_1[] =
6379 0xfffe0101, /* vs_1_1 */
6380 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6381 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6382 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6383 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6384 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6385 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6386 0x0000ffff /* end */
6388 static const DWORD swapped_shader_code_2[] =
6390 0xfffe0200, /* vs_2_0 */
6391 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6392 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6393 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6394 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6395 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6396 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6397 0x0000ffff /* end */
6399 static const DWORD texcoord_color_shader_code_3[] =
6401 0xfffe0300, /* vs_3_0 */
6402 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6403 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6404 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6405 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6406 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6407 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6408 0x0000ffff /* end */
6410 static const DWORD texcoord_color_shader_code_2[] =
6412 0xfffe0200, /* vs_2_0 */
6413 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6414 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6415 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6416 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6417 0x0000ffff /* end */
6419 static const DWORD texcoord_color_shader_code_1[] =
6421 0xfffe0101, /* vs_1_1 */
6422 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6423 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6424 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6425 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6426 0x0000ffff /* end */
6428 static const DWORD color_color_shader_code_3[] =
6430 0xfffe0300, /* vs_3_0 */
6431 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6432 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6433 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6434 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6435 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6436 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6437 0x0000ffff /* end */
6439 static const DWORD color_color_shader_code_2[] =
6441 0xfffe0200, /* vs_2_0 */
6442 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6443 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6444 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6445 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6446 0x0000ffff /* end */
6448 static const DWORD color_color_shader_code_1[] =
6450 0xfffe0101, /* vs_1_1 */
6451 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6452 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6453 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6454 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6455 0x0000ffff /* end */
6457 static const DWORD ps3_code[] =
6459 0xffff0300, /* ps_3_0 */
6460 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6461 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6462 0x0000ffff /* end */
6464 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6465 IDirect3DPixelShader9 *ps;
6466 HRESULT hr;
6467 DWORD color;
6468 float quad1[] = {
6469 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6470 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6471 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6472 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6474 float quad2[] = {
6475 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6476 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6477 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6478 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6480 float quad3[] = {
6481 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6482 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6483 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6484 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6486 float quad4[] = {
6487 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6488 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6489 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6490 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6492 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6493 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6494 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6495 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6496 D3DDECL_END()
6498 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6499 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6500 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6501 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6502 D3DDECL_END()
6504 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6505 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6506 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6507 D3DDECL_END()
6509 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6510 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6511 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6512 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6513 D3DDECL_END()
6515 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6516 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6517 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6518 D3DDECL_END()
6520 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6521 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6522 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6523 D3DDECL_END()
6525 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6526 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6527 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6528 D3DDECL_END()
6530 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6531 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6532 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6533 D3DDECL_END()
6535 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6536 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6537 unsigned int i;
6538 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6539 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6541 struct vertex quad1_color[] = {
6542 {-1.0, -1.0, 0.1, 0x00ff8040},
6543 { 0.0, -1.0, 0.1, 0x00ff8040},
6544 {-1.0, 0.0, 0.1, 0x00ff8040},
6545 { 0.0, 0.0, 0.1, 0x00ff8040}
6547 struct vertex quad2_color[] = {
6548 { 0.0, -1.0, 0.1, 0x00ff8040},
6549 { 1.0, -1.0, 0.1, 0x00ff8040},
6550 { 0.0, 0.0, 0.1, 0x00ff8040},
6551 { 1.0, 0.0, 0.1, 0x00ff8040}
6553 struct vertex quad3_color[] = {
6554 {-1.0, 0.0, 0.1, 0x00ff8040},
6555 { 0.0, 0.0, 0.1, 0x00ff8040},
6556 {-1.0, 1.0, 0.1, 0x00ff8040},
6557 { 0.0, 1.0, 0.1, 0x00ff8040}
6559 float quad4_color[] = {
6560 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6561 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6562 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6563 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6566 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6567 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6568 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6570 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6571 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6572 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6573 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6575 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6576 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6577 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6578 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6579 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6580 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6581 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6582 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6584 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6585 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6587 for(i = 1; i <= 3; i++) {
6588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6589 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6590 if(i == 3) {
6591 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6593 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6595 } else if(i == 2){
6596 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6597 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6598 } else if(i == 1) {
6599 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6603 hr = IDirect3DDevice9_BeginScene(device);
6604 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6605 if(SUCCEEDED(hr))
6607 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6608 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6610 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6611 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6612 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6613 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6615 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6616 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6618 if(i == 3 || i == 2) {
6619 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6620 } else if(i == 1) {
6621 /* Succeeds or fails, depending on SW or HW vertex processing */
6622 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6625 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6626 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6628 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6630 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6631 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6633 if(i == 3 || i == 2) {
6634 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6635 } else if(i == 1) {
6636 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6639 hr = IDirect3DDevice9_EndScene(device);
6640 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6643 if(i == 3 || i == 2) {
6644 color = getPixelColor(device, 160, 360);
6645 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6646 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6648 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6649 color = getPixelColor(device, 480, 360);
6650 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6651 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6652 color = getPixelColor(device, 160, 120);
6653 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6654 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6655 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6657 color = getPixelColor(device, 480, 160);
6658 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6659 } else if(i == 1) {
6660 color = getPixelColor(device, 160, 360);
6661 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6662 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6663 color = getPixelColor(device, 480, 360);
6664 /* Accept the clear color as well in this case, since SW VP returns an error */
6665 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6666 color = getPixelColor(device, 160, 120);
6667 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6668 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6669 color = getPixelColor(device, 480, 160);
6670 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6673 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6674 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6676 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6679 /* Now find out if the whole streams are re-read, or just the last active value for the
6680 * vertices is used.
6682 hr = IDirect3DDevice9_BeginScene(device);
6683 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6684 if(SUCCEEDED(hr))
6686 float quad1_modified[] = {
6687 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6688 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6689 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6690 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6692 float quad2_modified[] = {
6693 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6694 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6695 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6696 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6699 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6702 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6703 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6705 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6707 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6708 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6710 if(i == 3 || i == 2) {
6711 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6712 } else if(i == 1) {
6713 /* Succeeds or fails, depending on SW or HW vertex processing */
6714 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6717 hr = IDirect3DDevice9_EndScene(device);
6718 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6721 color = getPixelColor(device, 480, 350);
6722 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6723 * as well.
6725 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6726 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6727 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6728 * refrast's result.
6730 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6732 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6733 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6735 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6738 IDirect3DDevice9_SetVertexShader(device, NULL);
6739 IDirect3DDevice9_SetPixelShader(device, NULL);
6740 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6742 IDirect3DVertexShader9_Release(swapped_shader);
6745 for(i = 1; i <= 3; i++) {
6746 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6747 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6748 if(i == 3) {
6749 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6751 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6753 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6754 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6755 } else if(i == 2){
6756 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6757 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6758 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6759 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6760 } else if(i == 1) {
6761 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6762 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6763 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6764 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6767 hr = IDirect3DDevice9_BeginScene(device);
6768 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6769 if(SUCCEEDED(hr))
6771 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6772 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6773 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6774 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6776 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6778 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6779 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6781 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6782 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6783 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6784 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6786 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6788 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6789 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6790 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6791 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6793 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6795 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6796 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6798 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6800 hr = IDirect3DDevice9_EndScene(device);
6801 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6803 IDirect3DDevice9_SetVertexShader(device, NULL);
6804 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6805 IDirect3DDevice9_SetPixelShader(device, NULL);
6807 color = getPixelColor(device, 160, 360);
6808 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6809 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6810 color = getPixelColor(device, 480, 360);
6811 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6812 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6813 color = getPixelColor(device, 160, 120);
6814 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6815 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6816 color = getPixelColor(device, 480, 160);
6817 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6818 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6821 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6823 IDirect3DVertexShader9_Release(texcoord_color_shader);
6824 IDirect3DVertexShader9_Release(color_color_shader);
6827 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6828 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6829 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6830 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6832 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6833 IDirect3DVertexDeclaration9_Release(decl_color_color);
6834 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6835 IDirect3DVertexDeclaration9_Release(decl_color_float);
6837 IDirect3DPixelShader9_Release(ps);
6840 static void srgbtexture_test(IDirect3DDevice9 *device)
6842 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6843 * texture stage state to render a quad using that texture. The resulting
6844 * color components should be 0x36 (~ 0.21), per this formula:
6845 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6846 * This is true where srgb_color > 0.04045.
6848 IDirect3D9 *d3d = NULL;
6849 HRESULT hr;
6850 LPDIRECT3DTEXTURE9 texture = NULL;
6851 LPDIRECT3DSURFACE9 surface = NULL;
6852 D3DLOCKED_RECT lr;
6853 DWORD color;
6854 float quad[] = {
6855 -1.0, 1.0, 0.0, 0.0, 0.0,
6856 1.0, 1.0, 0.0, 1.0, 0.0,
6857 -1.0, -1.0, 0.0, 0.0, 1.0,
6858 1.0, -1.0, 0.0, 1.0, 1.0,
6862 memset(&lr, 0, sizeof(lr));
6863 IDirect3DDevice9_GetDirect3D(device, &d3d);
6864 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6865 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6866 D3DFMT_A8R8G8B8) != D3D_OK) {
6867 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6868 goto out;
6871 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6872 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6873 &texture, NULL);
6874 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6875 if(!texture) {
6876 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6877 goto out;
6879 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6880 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6882 fill_surface(surface, 0xff7f7f7f);
6883 IDirect3DSurface9_Release(surface);
6885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6887 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6890 hr = IDirect3DDevice9_BeginScene(device);
6891 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6892 if(SUCCEEDED(hr))
6894 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6895 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6897 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6898 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6902 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6904 hr = IDirect3DDevice9_EndScene(device);
6905 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6908 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6909 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6910 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6911 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6913 color = getPixelColor(device, 320, 240);
6914 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6916 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6917 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6919 out:
6920 if(texture) IDirect3DTexture9_Release(texture);
6921 IDirect3D9_Release(d3d);
6924 static void shademode_test(IDirect3DDevice9 *device)
6926 /* Render a quad and try all of the different fixed function shading models. */
6927 HRESULT hr;
6928 DWORD color0, color1;
6929 DWORD color0_gouraud = 0, color1_gouraud = 0;
6930 DWORD shademode = D3DSHADE_FLAT;
6931 DWORD primtype = D3DPT_TRIANGLESTRIP;
6932 LPVOID data = NULL;
6933 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6934 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6935 UINT i, j;
6936 struct vertex quad_strip[] =
6938 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6939 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6940 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6941 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6943 struct vertex quad_list[] =
6945 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6946 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6947 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6949 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6950 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6951 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6954 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6955 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6956 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6957 if (FAILED(hr)) goto bail;
6959 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6960 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6961 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6962 if (FAILED(hr)) goto bail;
6964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6967 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6968 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6970 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6971 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6972 memcpy(data, quad_strip, sizeof(quad_strip));
6973 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6974 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6976 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6977 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6978 memcpy(data, quad_list, sizeof(quad_list));
6979 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6980 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6982 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6983 * the color fixups we have to do for FLAT shading will be dependent on that. */
6984 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6985 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6987 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6988 for (j=0; j<2; j++) {
6990 /* Inner loop just changes the D3DRS_SHADEMODE */
6991 for (i=0; i<3; i++) {
6992 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6993 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6998 hr = IDirect3DDevice9_BeginScene(device);
6999 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7000 if(SUCCEEDED(hr))
7002 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7003 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7005 hr = IDirect3DDevice9_EndScene(device);
7006 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7009 /* Sample two spots from the output */
7010 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7011 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7012 switch(shademode) {
7013 case D3DSHADE_FLAT:
7014 /* Should take the color of the first vertex of each triangle */
7015 if (0)
7017 /* This test depends on EXT_provoking_vertex being
7018 * available. This extension is currently (20090810)
7019 * not common enough to let the test fail if it isn't
7020 * present. */
7021 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7022 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7024 shademode = D3DSHADE_GOURAUD;
7025 break;
7026 case D3DSHADE_GOURAUD:
7027 /* Should be an interpolated blend */
7029 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7030 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7031 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7032 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7034 color0_gouraud = color0;
7035 color1_gouraud = color1;
7037 shademode = D3DSHADE_PHONG;
7038 break;
7039 case D3DSHADE_PHONG:
7040 /* Should be the same as GOURAUD, since no hardware implements this */
7041 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7042 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7043 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7044 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7046 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7047 color0_gouraud, color0);
7048 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7049 color1_gouraud, color1);
7050 break;
7054 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7055 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7057 /* Now, do it all over again with a TRIANGLELIST */
7058 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7059 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7060 primtype = D3DPT_TRIANGLELIST;
7061 shademode = D3DSHADE_FLAT;
7064 bail:
7065 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7066 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7068 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7070 if (vb_strip)
7071 IDirect3DVertexBuffer9_Release(vb_strip);
7072 if (vb_list)
7073 IDirect3DVertexBuffer9_Release(vb_list);
7076 static void alpha_test(IDirect3DDevice9 *device)
7078 HRESULT hr;
7079 IDirect3DTexture9 *offscreenTexture;
7080 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7081 DWORD color;
7083 struct vertex quad1[] =
7085 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7086 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7087 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7088 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7090 struct vertex quad2[] =
7092 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7093 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7094 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7095 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7097 static const float composite_quad[][5] = {
7098 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7099 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7100 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7101 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7104 /* Clear the render target with alpha = 0.5 */
7105 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7106 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7108 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7109 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7111 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7112 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7113 if(!backbuffer) {
7114 goto out;
7117 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7118 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7119 if(!offscreen) {
7120 goto out;
7123 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7124 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7126 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7127 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7128 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7129 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7130 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7131 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7132 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7133 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7135 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7138 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7139 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7141 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7147 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7152 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7154 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7156 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7157 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7158 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7159 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7160 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7162 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7165 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7167 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7169 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7174 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7176 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7178 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7179 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7181 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7182 * Disable alpha blending for the final composition
7184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7185 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7186 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7187 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7189 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7190 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7191 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7192 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7193 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7194 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7196 hr = IDirect3DDevice9_EndScene(device);
7197 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7200 color = getPixelColor(device, 160, 360);
7201 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7202 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7204 color = getPixelColor(device, 160, 120);
7205 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7206 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7208 color = getPixelColor(device, 480, 360);
7209 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7210 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7212 color = getPixelColor(device, 480, 120);
7213 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7214 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7216 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7218 out:
7219 /* restore things */
7220 if(backbuffer) {
7221 IDirect3DSurface9_Release(backbuffer);
7223 if(offscreenTexture) {
7224 IDirect3DTexture9_Release(offscreenTexture);
7226 if(offscreen) {
7227 IDirect3DSurface9_Release(offscreen);
7231 struct vertex_shortcolor {
7232 float x, y, z;
7233 unsigned short r, g, b, a;
7235 struct vertex_floatcolor {
7236 float x, y, z;
7237 float r, g, b, a;
7240 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7242 HRESULT hr;
7243 BOOL s_ok, ub_ok, f_ok;
7244 DWORD color, size, i;
7245 void *data;
7246 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7247 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7248 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7249 D3DDECL_END()
7251 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7252 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7253 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7254 D3DDECL_END()
7256 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7257 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7258 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7259 D3DDECL_END()
7261 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7262 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7263 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7264 D3DDECL_END()
7266 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7267 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7268 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7269 D3DDECL_END()
7271 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7272 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7273 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7274 D3DDECL_END()
7276 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7277 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7278 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7279 D3DDECL_END()
7281 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7282 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7283 IDirect3DVertexBuffer9 *vb, *vb2;
7284 struct vertex quad1[] = /* D3DCOLOR */
7286 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7287 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7288 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7289 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7291 struct vertex quad2[] = /* UBYTE4N */
7293 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7294 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7295 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7296 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7298 struct vertex_shortcolor quad3[] = /* short */
7300 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7301 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7302 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7303 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7305 struct vertex_floatcolor quad4[] =
7307 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7308 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7309 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7310 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7312 DWORD colors[] = {
7313 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7314 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7315 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7316 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7317 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7318 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7319 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7320 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7321 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7322 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7323 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7324 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7325 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7326 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7327 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7328 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7330 float quads[] = {
7331 -1.0, -1.0, 0.1,
7332 -1.0, 0.0, 0.1,
7333 0.0, -1.0, 0.1,
7334 0.0, 0.0, 0.1,
7336 0.0, -1.0, 0.1,
7337 0.0, 0.0, 0.1,
7338 1.0, -1.0, 0.1,
7339 1.0, 0.0, 0.1,
7341 0.0, 0.0, 0.1,
7342 0.0, 1.0, 0.1,
7343 1.0, 0.0, 0.1,
7344 1.0, 1.0, 0.1,
7346 -1.0, 0.0, 0.1,
7347 -1.0, 1.0, 0.1,
7348 0.0, 0.0, 0.1,
7349 0.0, 1.0, 0.1
7351 struct tvertex quad_transformed[] = {
7352 { 90, 110, 0.1, 2.0, 0x00ffff00},
7353 { 570, 110, 0.1, 2.0, 0x00ffff00},
7354 { 90, 300, 0.1, 2.0, 0x00ffff00},
7355 { 570, 300, 0.1, 2.0, 0x00ffff00}
7357 D3DCAPS9 caps;
7359 memset(&caps, 0, sizeof(caps));
7360 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7361 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7363 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7364 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7366 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7367 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7368 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7369 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7370 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7371 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7372 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7373 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7374 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7375 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7376 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7377 } else {
7378 trace("D3DDTCAPS_UBYTE4N not supported\n");
7379 dcl_ubyte_2 = NULL;
7380 dcl_ubyte = NULL;
7382 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7383 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7384 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7385 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7387 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7388 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7389 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7390 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7392 hr = IDirect3DDevice9_BeginScene(device);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7394 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7395 if(SUCCEEDED(hr)) {
7396 if(dcl_color) {
7397 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7398 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7400 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7403 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7404 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7405 * using software vertex processing. Doh!
7407 if(dcl_ubyte) {
7408 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7409 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7411 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7412 ub_ok = SUCCEEDED(hr);
7415 if(dcl_short) {
7416 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7417 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7419 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7420 s_ok = SUCCEEDED(hr);
7423 if(dcl_float) {
7424 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7425 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7427 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7428 f_ok = SUCCEEDED(hr);
7431 hr = IDirect3DDevice9_EndScene(device);
7432 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7435 if(dcl_short) {
7436 color = getPixelColor(device, 480, 360);
7437 ok(color == 0x000000ff || !s_ok,
7438 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7440 if(dcl_ubyte) {
7441 color = getPixelColor(device, 160, 120);
7442 ok(color == 0x0000ffff || !ub_ok,
7443 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7445 if(dcl_color) {
7446 color = getPixelColor(device, 160, 360);
7447 ok(color == 0x00ffff00,
7448 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7450 if(dcl_float) {
7451 color = getPixelColor(device, 480, 120);
7452 ok(color == 0x00ff0000 || !f_ok,
7453 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7455 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7457 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7458 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7459 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7460 * whether the immediate mode code works
7462 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7463 hr = IDirect3DDevice9_BeginScene(device);
7464 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7465 if(SUCCEEDED(hr)) {
7466 if(dcl_color) {
7467 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7468 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7469 memcpy(data, quad1, sizeof(quad1));
7470 hr = IDirect3DVertexBuffer9_Unlock(vb);
7471 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7472 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7473 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7474 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7475 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7476 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7477 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7480 if(dcl_ubyte) {
7481 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7482 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7483 memcpy(data, quad2, sizeof(quad2));
7484 hr = IDirect3DVertexBuffer9_Unlock(vb);
7485 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7486 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7487 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7488 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7489 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7490 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7491 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7492 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7493 ub_ok = SUCCEEDED(hr);
7496 if(dcl_short) {
7497 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7498 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7499 memcpy(data, quad3, sizeof(quad3));
7500 hr = IDirect3DVertexBuffer9_Unlock(vb);
7501 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7502 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7503 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7504 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7505 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7506 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7507 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7508 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7509 s_ok = SUCCEEDED(hr);
7512 if(dcl_float) {
7513 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7514 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7515 memcpy(data, quad4, sizeof(quad4));
7516 hr = IDirect3DVertexBuffer9_Unlock(vb);
7517 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7518 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7520 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7521 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7522 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7523 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7524 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7525 f_ok = SUCCEEDED(hr);
7528 hr = IDirect3DDevice9_EndScene(device);
7529 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7532 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7533 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7534 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7535 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7537 if(dcl_short) {
7538 color = getPixelColor(device, 480, 360);
7539 ok(color == 0x000000ff || !s_ok,
7540 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7542 if(dcl_ubyte) {
7543 color = getPixelColor(device, 160, 120);
7544 ok(color == 0x0000ffff || !ub_ok,
7545 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7547 if(dcl_color) {
7548 color = getPixelColor(device, 160, 360);
7549 ok(color == 0x00ffff00,
7550 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7552 if(dcl_float) {
7553 color = getPixelColor(device, 480, 120);
7554 ok(color == 0x00ff0000 || !f_ok,
7555 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7557 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7562 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7563 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7564 memcpy(data, quad_transformed, sizeof(quad_transformed));
7565 hr = IDirect3DVertexBuffer9_Unlock(vb);
7566 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7568 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7569 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7571 hr = IDirect3DDevice9_BeginScene(device);
7572 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7573 if(SUCCEEDED(hr)) {
7574 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7575 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7576 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7577 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7579 hr = IDirect3DDevice9_EndScene(device);
7580 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7583 color = getPixelColor(device, 88, 108);
7584 ok(color == 0x000000ff,
7585 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7586 color = getPixelColor(device, 92, 108);
7587 ok(color == 0x000000ff,
7588 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7589 color = getPixelColor(device, 88, 112);
7590 ok(color == 0x000000ff,
7591 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7592 color = getPixelColor(device, 92, 112);
7593 ok(color == 0x00ffff00,
7594 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7596 color = getPixelColor(device, 568, 108);
7597 ok(color == 0x000000ff,
7598 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7599 color = getPixelColor(device, 572, 108);
7600 ok(color == 0x000000ff,
7601 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7602 color = getPixelColor(device, 568, 112);
7603 ok(color == 0x00ffff00,
7604 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7605 color = getPixelColor(device, 572, 112);
7606 ok(color == 0x000000ff,
7607 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7609 color = getPixelColor(device, 88, 298);
7610 ok(color == 0x000000ff,
7611 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7612 color = getPixelColor(device, 92, 298);
7613 ok(color == 0x00ffff00,
7614 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7615 color = getPixelColor(device, 88, 302);
7616 ok(color == 0x000000ff,
7617 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7618 color = getPixelColor(device, 92, 302);
7619 ok(color == 0x000000ff,
7620 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7622 color = getPixelColor(device, 568, 298);
7623 ok(color == 0x00ffff00,
7624 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7625 color = getPixelColor(device, 572, 298);
7626 ok(color == 0x000000ff,
7627 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7628 color = getPixelColor(device, 568, 302);
7629 ok(color == 0x000000ff,
7630 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7631 color = getPixelColor(device, 572, 302);
7632 ok(color == 0x000000ff,
7633 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7635 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7637 /* This test is pointless without those two declarations: */
7638 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7639 skip("color-ubyte switching test declarations aren't supported\n");
7640 goto out;
7643 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7644 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7645 memcpy(data, quads, sizeof(quads));
7646 hr = IDirect3DVertexBuffer9_Unlock(vb);
7647 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7648 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7649 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7650 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7651 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7652 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7653 memcpy(data, colors, sizeof(colors));
7654 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7655 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7657 for(i = 0; i < 2; i++) {
7658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7659 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7661 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7662 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7663 if(i == 0) {
7664 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7665 } else {
7666 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7670 hr = IDirect3DDevice9_BeginScene(device);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7672 ub_ok = FALSE;
7673 if(SUCCEEDED(hr)) {
7674 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7675 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7676 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7677 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7678 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7679 ub_ok = SUCCEEDED(hr);
7681 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7682 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7683 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7684 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7686 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7688 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7689 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7690 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7691 ub_ok = (SUCCEEDED(hr) && ub_ok);
7693 hr = IDirect3DDevice9_EndScene(device);
7694 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7697 if(i == 0) {
7698 color = getPixelColor(device, 480, 360);
7699 ok(color == 0x00ff0000,
7700 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7701 color = getPixelColor(device, 160, 120);
7702 ok(color == 0x00ffffff,
7703 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7704 color = getPixelColor(device, 160, 360);
7705 ok(color == 0x000000ff || !ub_ok,
7706 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7707 color = getPixelColor(device, 480, 120);
7708 ok(color == 0x000000ff || !ub_ok,
7709 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7710 } else {
7711 color = getPixelColor(device, 480, 360);
7712 ok(color == 0x000000ff,
7713 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7714 color = getPixelColor(device, 160, 120);
7715 ok(color == 0x00ffffff,
7716 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7717 color = getPixelColor(device, 160, 360);
7718 ok(color == 0x00ff0000 || !ub_ok,
7719 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7720 color = getPixelColor(device, 480, 120);
7721 ok(color == 0x00ff0000 || !ub_ok,
7722 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7724 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7727 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7728 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7729 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7730 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7731 IDirect3DVertexBuffer9_Release(vb2);
7733 out:
7734 IDirect3DVertexBuffer9_Release(vb);
7735 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7736 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7737 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7738 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7739 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7740 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7741 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7744 struct vertex_float16color {
7745 float x, y, z;
7746 DWORD c1, c2;
7749 static void test_vshader_float16(IDirect3DDevice9 *device)
7751 HRESULT hr;
7752 DWORD color;
7753 void *data;
7754 static const D3DVERTEXELEMENT9 decl_elements[] = {
7755 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7756 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7757 D3DDECL_END()
7759 IDirect3DVertexDeclaration9 *vdecl = NULL;
7760 IDirect3DVertexBuffer9 *buffer = NULL;
7761 IDirect3DVertexShader9 *shader;
7762 DWORD shader_code[] = {
7763 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7764 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7765 0x90e40001, 0x0000ffff
7767 struct vertex_float16color quad[] = {
7768 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7769 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7770 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7771 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7773 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7774 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7775 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7776 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7778 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7779 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7780 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7781 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7783 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7784 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7785 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7786 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7789 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7790 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7792 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7793 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7794 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7795 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7796 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7797 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7799 hr = IDirect3DDevice9_BeginScene(device);
7800 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7801 if(SUCCEEDED(hr)) {
7802 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7803 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7805 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7807 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7809 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7810 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7811 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7813 hr = IDirect3DDevice9_EndScene(device);
7814 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7816 color = getPixelColor(device, 480, 360);
7817 ok(color == 0x00ff0000,
7818 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7819 color = getPixelColor(device, 160, 120);
7820 ok(color == 0x00000000,
7821 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7822 color = getPixelColor(device, 160, 360);
7823 ok(color == 0x0000ff00,
7824 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7825 color = getPixelColor(device, 480, 120);
7826 ok(color == 0x000000ff,
7827 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7828 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7830 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7831 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7833 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7834 D3DPOOL_MANAGED, &buffer, NULL);
7835 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7836 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7837 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7838 memcpy(data, quad, sizeof(quad));
7839 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7840 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7841 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7842 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7844 hr = IDirect3DDevice9_BeginScene(device);
7845 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7846 if(SUCCEEDED(hr)) {
7847 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7848 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7849 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7850 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7851 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7852 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7853 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7854 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7856 hr = IDirect3DDevice9_EndScene(device);
7857 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7860 color = getPixelColor(device, 480, 360);
7861 ok(color == 0x00ff0000,
7862 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7863 color = getPixelColor(device, 160, 120);
7864 ok(color == 0x00000000,
7865 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7866 color = getPixelColor(device, 160, 360);
7867 ok(color == 0x0000ff00,
7868 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7869 color = getPixelColor(device, 480, 120);
7870 ok(color == 0x000000ff,
7871 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7872 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7874 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7875 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7876 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7878 IDirect3DDevice9_SetVertexShader(device, NULL);
7879 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7881 IDirect3DVertexDeclaration9_Release(vdecl);
7882 IDirect3DVertexShader9_Release(shader);
7883 IDirect3DVertexBuffer9_Release(buffer);
7886 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7888 D3DCAPS9 caps;
7889 IDirect3DTexture9 *texture;
7890 HRESULT hr;
7891 D3DLOCKED_RECT rect;
7892 unsigned int x, y;
7893 DWORD *dst, color;
7894 const float quad[] = {
7895 -1.0, -1.0, 0.1, -0.2, -0.2,
7896 1.0, -1.0, 0.1, 1.2, -0.2,
7897 -1.0, 1.0, 0.1, -0.2, 1.2,
7898 1.0, 1.0, 0.1, 1.2, 1.2
7900 memset(&caps, 0, sizeof(caps));
7902 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7904 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7906 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7907 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7908 "Card has conditional NP2 support without power of two restriction set\n");
7910 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
7912 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7913 return;
7915 else
7917 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
7918 return;
7921 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7922 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7924 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7925 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7927 memset(&rect, 0, sizeof(rect));
7928 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7929 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7930 for(y = 0; y < 10; y++) {
7931 for(x = 0; x < 10; x++) {
7932 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7933 if(x == 0 || x == 9 || y == 0 || y == 9) {
7934 *dst = 0x00ff0000;
7935 } else {
7936 *dst = 0x000000ff;
7940 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7941 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7943 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7944 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7945 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7946 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7947 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7948 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7949 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7950 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7952 hr = IDirect3DDevice9_BeginScene(device);
7953 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7954 if(SUCCEEDED(hr)) {
7955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7956 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7958 hr = IDirect3DDevice9_EndScene(device);
7959 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7962 color = getPixelColor(device, 1, 1);
7963 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7964 color = getPixelColor(device, 639, 479);
7965 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7967 color = getPixelColor(device, 135, 101);
7968 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7969 color = getPixelColor(device, 140, 101);
7970 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7971 color = getPixelColor(device, 135, 105);
7972 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7973 color = getPixelColor(device, 140, 105);
7974 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7976 color = getPixelColor(device, 135, 376);
7977 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7978 color = getPixelColor(device, 140, 376);
7979 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7980 color = getPixelColor(device, 135, 379);
7981 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7982 color = getPixelColor(device, 140, 379);
7983 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7985 color = getPixelColor(device, 500, 101);
7986 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7987 color = getPixelColor(device, 504, 101);
7988 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7989 color = getPixelColor(device, 500, 105);
7990 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7991 color = getPixelColor(device, 504, 105);
7992 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7994 color = getPixelColor(device, 500, 376);
7995 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7996 color = getPixelColor(device, 504, 376);
7997 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7998 color = getPixelColor(device, 500, 380);
7999 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8000 color = getPixelColor(device, 504, 380);
8001 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8003 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8005 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8006 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8007 IDirect3DTexture9_Release(texture);
8010 static void vFace_register_test(IDirect3DDevice9 *device)
8012 HRESULT hr;
8013 DWORD color;
8014 const DWORD shader_code[] = {
8015 0xffff0300, /* ps_3_0 */
8016 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8017 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8018 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8019 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8020 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8021 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8022 0x0000ffff /* END */
8024 const DWORD vshader_code[] = {
8025 0xfffe0300, /* vs_3_0 */
8026 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8027 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8028 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8029 0x0000ffff /* end */
8031 IDirect3DPixelShader9 *shader;
8032 IDirect3DVertexShader9 *vshader;
8033 IDirect3DTexture9 *texture;
8034 IDirect3DSurface9 *surface, *backbuffer;
8035 const float quad[] = {
8036 -1.0, -1.0, 0.1,
8037 1.0, -1.0, 0.1,
8038 -1.0, 0.0, 0.1,
8040 1.0, -1.0, 0.1,
8041 1.0, 0.0, 0.1,
8042 -1.0, 0.0, 0.1,
8044 -1.0, 0.0, 0.1,
8045 -1.0, 1.0, 0.1,
8046 1.0, 0.0, 0.1,
8048 1.0, 0.0, 0.1,
8049 -1.0, 1.0, 0.1,
8050 1.0, 1.0, 0.1,
8052 const float blit[] = {
8053 0.0, -1.0, 0.1, 0.0, 0.0,
8054 1.0, -1.0, 0.1, 1.0, 0.0,
8055 0.0, 1.0, 0.1, 0.0, 1.0,
8056 1.0, 1.0, 0.1, 1.0, 1.0,
8059 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8060 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8061 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8062 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8063 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8064 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8065 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8066 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8067 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8068 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8069 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8070 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8071 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8072 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8073 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8074 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8076 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8077 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8079 hr = IDirect3DDevice9_BeginScene(device);
8080 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8081 if(SUCCEEDED(hr)) {
8082 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8083 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8084 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8086 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8088 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8089 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8090 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8092 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8094 /* Blit the texture onto the back buffer to make it visible */
8095 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8096 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8097 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8098 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8099 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8100 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8101 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8103 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8104 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8105 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8106 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8109 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8111 hr = IDirect3DDevice9_EndScene(device);
8112 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8115 color = getPixelColor(device, 160, 360);
8116 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8117 color = getPixelColor(device, 160, 120);
8118 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8119 color = getPixelColor(device, 480, 360);
8120 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8121 color = getPixelColor(device, 480, 120);
8122 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8123 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8126 IDirect3DDevice9_SetTexture(device, 0, NULL);
8127 IDirect3DPixelShader9_Release(shader);
8128 IDirect3DVertexShader9_Release(vshader);
8129 IDirect3DSurface9_Release(surface);
8130 IDirect3DSurface9_Release(backbuffer);
8131 IDirect3DTexture9_Release(texture);
8134 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8136 HRESULT hr;
8137 DWORD color;
8138 int i;
8139 D3DCAPS9 caps;
8140 BOOL L6V5U5_supported = FALSE;
8141 IDirect3DTexture9 *tex1, *tex2;
8142 D3DLOCKED_RECT locked_rect;
8144 static const float quad[][7] = {
8145 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8146 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8147 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8148 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8151 static const D3DVERTEXELEMENT9 decl_elements[] = {
8152 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8153 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8154 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8155 D3DDECL_END()
8158 /* use asymmetric matrix to test loading */
8159 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8160 float scale, offset;
8162 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8163 IDirect3DTexture9 *texture = NULL;
8165 memset(&caps, 0, sizeof(caps));
8166 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8167 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8168 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8169 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8170 return;
8171 } else {
8172 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8173 * They report that it is not supported, but after that bump mapping works properly. So just test
8174 * if the format is generally supported, and check the BUMPENVMAP flag
8176 IDirect3D9 *d3d9;
8178 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8179 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8180 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8181 L6V5U5_supported = SUCCEEDED(hr);
8182 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8183 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8184 IDirect3D9_Release(d3d9);
8185 if(FAILED(hr)) {
8186 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8187 return;
8191 /* Generate the textures */
8192 generate_bumpmap_textures(device);
8194 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8195 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8196 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8197 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8198 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8199 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8200 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8201 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8203 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8204 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8205 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8206 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8207 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8208 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8210 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8211 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8212 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8213 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8214 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8215 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8217 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8218 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8220 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8221 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8223 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8224 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8227 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8228 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8229 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8230 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8232 hr = IDirect3DDevice9_BeginScene(device);
8233 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8236 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8238 hr = IDirect3DDevice9_EndScene(device);
8239 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8241 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8242 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8243 * But since testing the color match is not the purpose of the test don't be too picky
8245 color = getPixelColor(device, 320-32, 240);
8246 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8247 color = getPixelColor(device, 320+32, 240);
8248 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8249 color = getPixelColor(device, 320, 240-32);
8250 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8251 color = getPixelColor(device, 320, 240+32);
8252 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8253 color = getPixelColor(device, 320, 240);
8254 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8255 color = getPixelColor(device, 320+32, 240+32);
8256 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8257 color = getPixelColor(device, 320-32, 240+32);
8258 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8259 color = getPixelColor(device, 320+32, 240-32);
8260 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8261 color = getPixelColor(device, 320-32, 240-32);
8262 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8264 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8266 for(i = 0; i < 2; i++) {
8267 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8268 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8269 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8270 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8271 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8272 IDirect3DTexture9_Release(texture); /* To destroy it */
8275 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8276 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8277 goto cleanup;
8279 if(L6V5U5_supported == FALSE) {
8280 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8281 goto cleanup;
8284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8285 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8286 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8287 * would only make this test more complicated
8289 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8290 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8291 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8292 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8294 memset(&locked_rect, 0, sizeof(locked_rect));
8295 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8296 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8297 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8298 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8299 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8301 memset(&locked_rect, 0, sizeof(locked_rect));
8302 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8303 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8304 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8305 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8306 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8308 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8309 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8310 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8311 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8313 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8314 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8315 scale = 2.0;
8316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8317 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8318 offset = 0.1;
8319 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8320 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8322 hr = IDirect3DDevice9_BeginScene(device);
8323 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8324 if(SUCCEEDED(hr)) {
8325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8326 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8327 hr = IDirect3DDevice9_EndScene(device);
8328 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8331 color = getPixelColor(device, 320, 240);
8332 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8333 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8334 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8336 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8338 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8340 /* Check a result scale factor > 1.0 */
8341 scale = 10;
8342 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8343 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8344 offset = 10;
8345 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8346 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8348 hr = IDirect3DDevice9_BeginScene(device);
8349 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8350 if(SUCCEEDED(hr)) {
8351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8352 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8353 hr = IDirect3DDevice9_EndScene(device);
8354 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8356 color = getPixelColor(device, 320, 240);
8357 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8359 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8361 /* Check clamping in the scale factor calculation */
8362 scale = 1000;
8363 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8364 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8365 offset = -1;
8366 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8367 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8369 hr = IDirect3DDevice9_BeginScene(device);
8370 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8371 if(SUCCEEDED(hr)) {
8372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8373 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8374 hr = IDirect3DDevice9_EndScene(device);
8375 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8377 color = getPixelColor(device, 320, 240);
8378 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8379 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8382 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8384 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8385 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8387 IDirect3DTexture9_Release(tex1);
8388 IDirect3DTexture9_Release(tex2);
8390 cleanup:
8391 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8392 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8393 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8394 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8396 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8397 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8398 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8401 static void stencil_cull_test(IDirect3DDevice9 *device) {
8402 HRESULT hr;
8403 IDirect3DSurface9 *depthstencil = NULL;
8404 D3DSURFACE_DESC desc;
8405 float quad1[] = {
8406 -1.0, -1.0, 0.1,
8407 0.0, -1.0, 0.1,
8408 -1.0, 0.0, 0.1,
8409 0.0, 0.0, 0.1,
8411 float quad2[] = {
8412 0.0, -1.0, 0.1,
8413 1.0, -1.0, 0.1,
8414 0.0, 0.0, 0.1,
8415 1.0, 0.0, 0.1,
8417 float quad3[] = {
8418 0.0, 0.0, 0.1,
8419 1.0, 0.0, 0.1,
8420 0.0, 1.0, 0.1,
8421 1.0, 1.0, 0.1,
8423 float quad4[] = {
8424 -1.0, 0.0, 0.1,
8425 0.0, 0.0, 0.1,
8426 -1.0, 1.0, 0.1,
8427 0.0, 1.0, 0.1,
8429 struct vertex painter[] = {
8430 {-1.0, -1.0, 0.0, 0x00000000},
8431 { 1.0, -1.0, 0.0, 0x00000000},
8432 {-1.0, 1.0, 0.0, 0x00000000},
8433 { 1.0, 1.0, 0.0, 0x00000000},
8435 WORD indices_cw[] = {0, 1, 3};
8436 WORD indices_ccw[] = {0, 2, 3};
8437 unsigned int i;
8438 DWORD color;
8440 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8441 if(depthstencil == NULL) {
8442 skip("No depth stencil buffer\n");
8443 return;
8445 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8446 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8447 IDirect3DSurface9_Release(depthstencil);
8448 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8449 skip("No 4 or 8 bit stencil surface\n");
8450 return;
8453 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8455 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8467 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8469 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8470 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8471 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8474 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8476 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8478 /* First pass: Fill the stencil buffer with some values... */
8479 hr = IDirect3DDevice9_BeginScene(device);
8480 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8481 if(SUCCEEDED(hr))
8483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8484 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8485 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8486 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8487 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8488 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8489 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8490 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8493 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8495 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8496 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8497 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8498 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8499 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8500 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8501 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8506 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8507 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8508 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8509 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8510 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8514 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8515 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8516 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8517 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8518 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8519 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8521 hr = IDirect3DDevice9_EndScene(device);
8522 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8525 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8531 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8533 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8535 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8537 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8539 /* 2nd pass: Make the stencil values visible */
8540 hr = IDirect3DDevice9_BeginScene(device);
8541 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8542 if(SUCCEEDED(hr))
8544 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8545 for(i = 0; i < 16; i++) {
8546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8549 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8550 painter[1].diffuse = (i * 16);
8551 painter[2].diffuse = (i * 16);
8552 painter[3].diffuse = (i * 16);
8553 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8554 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8556 hr = IDirect3DDevice9_EndScene(device);
8557 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8561 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8563 color = getPixelColor(device, 160, 420);
8564 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8565 color = getPixelColor(device, 160, 300);
8566 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8568 color = getPixelColor(device, 480, 420);
8569 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8570 color = getPixelColor(device, 480, 300);
8571 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8573 color = getPixelColor(device, 160, 180);
8574 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8575 color = getPixelColor(device, 160, 60);
8576 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8578 color = getPixelColor(device, 480, 180);
8579 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8580 color = getPixelColor(device, 480, 60);
8581 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8583 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8584 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8587 static void vpos_register_test(IDirect3DDevice9 *device)
8589 HRESULT hr;
8590 DWORD color;
8591 const DWORD shader_code[] = {
8592 0xffff0300, /* ps_3_0 */
8593 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8594 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8595 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8596 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8597 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8598 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8599 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8600 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8601 0x0000ffff /* end */
8603 const DWORD shader_frac_code[] = {
8604 0xffff0300, /* ps_3_0 */
8605 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8606 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8607 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8608 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8609 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8610 0x0000ffff /* end */
8612 const DWORD vshader_code[] = {
8613 0xfffe0300, /* vs_3_0 */
8614 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8615 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8616 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8617 0x0000ffff /* end */
8619 IDirect3DVertexShader9 *vshader;
8620 IDirect3DPixelShader9 *shader, *shader_frac;
8621 IDirect3DSurface9 *surface = NULL, *backbuffer;
8622 const float quad[] = {
8623 -1.0, -1.0, 0.1, 0.0, 0.0,
8624 1.0, -1.0, 0.1, 1.0, 0.0,
8625 -1.0, 1.0, 0.1, 0.0, 1.0,
8626 1.0, 1.0, 0.1, 1.0, 1.0,
8628 D3DLOCKED_RECT lr;
8629 float constant[4] = {1.0, 0.0, 320, 240};
8630 DWORD *pos;
8632 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8633 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8634 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8635 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8636 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8637 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8638 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8639 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8640 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8641 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8642 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8643 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8644 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8645 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8646 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8649 hr = IDirect3DDevice9_BeginScene(device);
8650 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8651 if(SUCCEEDED(hr)) {
8652 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8653 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8655 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8656 hr = IDirect3DDevice9_EndScene(device);
8657 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8660 /* This has to be pixel exact */
8661 color = getPixelColor(device, 319, 239);
8662 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8663 color = getPixelColor(device, 320, 239);
8664 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8665 color = getPixelColor(device, 319, 240);
8666 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8667 color = getPixelColor(device, 320, 240);
8668 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8669 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8671 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8672 &surface, NULL);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8674 hr = IDirect3DDevice9_BeginScene(device);
8675 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8676 if(SUCCEEDED(hr)) {
8677 constant[2] = 16; constant[3] = 16;
8678 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8679 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8680 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8683 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8684 hr = IDirect3DDevice9_EndScene(device);
8685 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8687 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8688 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8690 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8691 color = *pos & 0x00ffffff;
8692 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8693 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8694 color = *pos & 0x00ffffff;
8695 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8696 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8697 color = *pos & 0x00ffffff;
8698 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8699 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8700 color = *pos & 0x00ffffff;
8701 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8703 hr = IDirect3DSurface9_UnlockRect(surface);
8704 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8706 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8707 * have full control over the multisampling setting inside this test
8709 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8710 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8711 hr = IDirect3DDevice9_BeginScene(device);
8712 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8713 if(SUCCEEDED(hr)) {
8714 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8715 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8717 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8718 hr = IDirect3DDevice9_EndScene(device);
8719 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8721 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8722 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8724 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8725 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8727 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8728 color = *pos & 0x00ffffff;
8729 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8731 hr = IDirect3DSurface9_UnlockRect(surface);
8732 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8734 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8735 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8736 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8737 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8738 IDirect3DPixelShader9_Release(shader);
8739 IDirect3DPixelShader9_Release(shader_frac);
8740 IDirect3DVertexShader9_Release(vshader);
8741 if(surface) IDirect3DSurface9_Release(surface);
8742 IDirect3DSurface9_Release(backbuffer);
8745 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8747 D3DCOLOR color;
8749 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8750 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8751 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8752 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8753 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8755 ++r;
8756 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8757 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8758 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8759 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8760 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8762 return TRUE;
8765 static void pointsize_test(IDirect3DDevice9 *device)
8767 HRESULT hr;
8768 D3DCAPS9 caps;
8769 D3DMATRIX matrix;
8770 D3DMATRIX identity;
8771 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8772 DWORD color;
8773 IDirect3DSurface9 *rt, *backbuffer;
8774 IDirect3DTexture9 *tex1, *tex2;
8775 RECT rect = {0, 0, 128, 128};
8776 D3DLOCKED_RECT lr;
8777 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8778 0x00000000, 0x00000000};
8779 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8780 0x00000000, 0x0000ff00};
8782 const float vertices[] = {
8783 64, 64, 0.1,
8784 128, 64, 0.1,
8785 192, 64, 0.1,
8786 256, 64, 0.1,
8787 320, 64, 0.1,
8788 384, 64, 0.1,
8789 448, 64, 0.1,
8790 512, 64, 0.1,
8793 /* 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 */
8794 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;
8795 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;
8796 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;
8797 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;
8799 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;
8800 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;
8801 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;
8802 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;
8804 memset(&caps, 0, sizeof(caps));
8805 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8806 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8807 if(caps.MaxPointSize < 32.0) {
8808 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8809 return;
8812 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8813 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8814 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8816 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8817 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8818 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8819 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8821 hr = IDirect3DDevice9_BeginScene(device);
8822 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8823 if (SUCCEEDED(hr))
8825 ptsize = 15.0;
8826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8827 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8829 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8831 ptsize = 31.0;
8832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8833 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8835 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8837 ptsize = 30.75;
8838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8841 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8843 if (caps.MaxPointSize >= 63.0)
8845 ptsize = 63.0;
8846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8847 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8849 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8851 ptsize = 62.75;
8852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8853 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8855 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8858 ptsize = 1.0;
8859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8860 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8862 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8864 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8865 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8866 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8867 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8869 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8870 ptsize = 15.0;
8871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8872 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8873 ptsize = 1.0;
8874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8875 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8877 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8880 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8882 /* pointsize < pointsize_min < pointsize_max?
8883 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8884 ptsize = 1.0;
8885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8887 ptsize = 15.0;
8888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8891 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8894 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8896 hr = IDirect3DDevice9_EndScene(device);
8897 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8900 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8901 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8902 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8904 if (caps.MaxPointSize >= 63.0)
8906 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8907 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8910 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8911 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8912 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8913 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8914 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8916 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8918 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8919 * generates texture coordinates for the point(result: Yes, it does)
8921 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8922 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8923 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8926 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8928 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8929 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8930 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8931 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8932 memset(&lr, 0, sizeof(lr));
8933 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8934 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8935 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8936 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8937 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8938 memset(&lr, 0, sizeof(lr));
8939 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8940 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8941 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8942 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8943 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8944 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8945 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8946 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8947 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8948 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8949 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8950 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8952 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8953 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8954 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8955 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8956 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8957 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8961 ptsize = 32.0;
8962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8963 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8965 hr = IDirect3DDevice9_BeginScene(device);
8966 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8967 if(SUCCEEDED(hr))
8969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8970 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8971 hr = IDirect3DDevice9_EndScene(device);
8972 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8975 color = getPixelColor(device, 64-4, 64-4);
8976 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8977 color = getPixelColor(device, 64-4, 64+4);
8978 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8979 color = getPixelColor(device, 64+4, 64+4);
8980 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8981 color = getPixelColor(device, 64+4, 64-4);
8982 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8983 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8985 U(matrix).m[0][0] = 1.0f / 64.0f;
8986 U(matrix).m[1][1] = -1.0f / 64.0f;
8987 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8988 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8990 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8991 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8993 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8994 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8995 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8997 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8998 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9000 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9002 hr = IDirect3DDevice9_BeginScene(device);
9003 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9005 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9006 hr = IDirect3DDevice9_EndScene(device);
9007 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9009 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9010 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9011 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9012 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9013 IDirect3DSurface9_Release(backbuffer);
9014 IDirect3DSurface9_Release(rt);
9016 color = getPixelColor(device, 64-4, 64-4);
9017 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9018 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9019 color = getPixelColor(device, 64+4, 64-4);
9020 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9021 "Expected color 0x00ffff00, got 0x%08x.\n", color);
9022 color = getPixelColor(device, 64-4, 64+4);
9023 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9024 "Expected color 0x00000000, got 0x%08x.\n", color);
9025 color = getPixelColor(device, 64+4, 64+4);
9026 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9027 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9029 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9030 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9032 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9033 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9034 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9035 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9036 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9037 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9038 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9039 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9040 IDirect3DTexture9_Release(tex1);
9041 IDirect3DTexture9_Release(tex2);
9043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9047 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9051 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9053 static const DWORD vshader_code[] =
9055 0xfffe0300, /* vs_3_0 */
9056 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9057 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9058 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9059 0x0000ffff /* end */
9061 static const DWORD pshader_code1[] =
9063 0xffff0300, /* ps_3_0 */
9064 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9065 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9066 0x0000ffff /* end */
9068 static const DWORD pshader_code2[] =
9070 0xffff0300, /* ps_3_0 */
9071 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9072 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9073 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9074 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9075 0x0000ffff /* end */
9078 HRESULT hr;
9079 IDirect3DVertexShader9 *vs;
9080 IDirect3DPixelShader9 *ps1, *ps2;
9081 IDirect3DTexture9 *tex1, *tex2;
9082 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9083 D3DCAPS9 caps;
9084 DWORD color;
9085 UINT i, j;
9086 float quad[] = {
9087 -1.0, -1.0, 0.1,
9088 1.0, -1.0, 0.1,
9089 -1.0, 1.0, 0.1,
9090 1.0, 1.0, 0.1,
9092 float texquad[] = {
9093 -1.0, -1.0, 0.1, 0.0, 0.0,
9094 0.0, -1.0, 0.1, 1.0, 0.0,
9095 -1.0, 1.0, 0.1, 0.0, 1.0,
9096 0.0, 1.0, 0.1, 1.0, 1.0,
9098 0.0, -1.0, 0.1, 0.0, 0.0,
9099 1.0, -1.0, 0.1, 1.0, 0.0,
9100 0.0, 1.0, 0.1, 0.0, 1.0,
9101 1.0, 1.0, 0.1, 1.0, 1.0,
9104 memset(&caps, 0, sizeof(caps));
9105 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9106 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9107 if(caps.NumSimultaneousRTs < 2) {
9108 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9109 return;
9112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9113 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9115 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9116 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9117 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9119 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9120 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9122 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9123 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9124 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9125 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9126 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9127 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9128 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9129 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9130 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9132 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9133 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9134 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9135 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9136 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9137 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9139 hr = IDirect3DDevice9_SetVertexShader(device, vs);
9140 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9141 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9142 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9143 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9144 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9145 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9146 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9148 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9149 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9150 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9151 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9152 color = getPixelColorFromSurface(readback, 8, 8);
9153 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9154 "Expected color 0x000000ff, got 0x%08x.\n", color);
9155 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9156 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9157 color = getPixelColorFromSurface(readback, 8, 8);
9158 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9159 "Expected color 0x000000ff, got 0x%08x.\n", color);
9161 /* Render targets not written by the pixel shader should be unmodified. */
9162 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9163 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9164 hr = IDirect3DDevice9_BeginScene(device);
9165 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9167 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9168 hr = IDirect3DDevice9_EndScene(device);
9169 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9170 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9171 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9172 color = getPixelColorFromSurface(readback, 8, 8);
9173 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9174 "Expected color 0xff00ff00, got 0x%08x.\n", color);
9175 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9176 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9177 for (i = 6; i < 10; ++i)
9179 for (j = 6; j < 10; ++j)
9181 color = getPixelColorFromSurface(readback, j, i);
9182 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9183 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9187 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9188 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9189 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9190 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9191 color = getPixelColorFromSurface(readback, 8, 8);
9192 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9193 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9194 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9195 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9196 color = getPixelColorFromSurface(readback, 8, 8);
9197 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9198 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9200 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9201 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9203 hr = IDirect3DDevice9_BeginScene(device);
9204 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9205 if(SUCCEEDED(hr)) {
9206 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9207 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9209 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9210 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9211 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9212 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9213 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9215 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9216 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9217 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9218 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9220 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9221 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9223 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9225 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9226 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9228 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9230 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9231 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9233 hr = IDirect3DDevice9_EndScene(device);
9234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9237 color = getPixelColor(device, 160, 240);
9238 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9239 color = getPixelColor(device, 480, 240);
9240 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9241 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9243 IDirect3DPixelShader9_Release(ps2);
9244 IDirect3DPixelShader9_Release(ps1);
9245 IDirect3DVertexShader9_Release(vs);
9246 IDirect3DTexture9_Release(tex1);
9247 IDirect3DTexture9_Release(tex2);
9248 IDirect3DSurface9_Release(surf1);
9249 IDirect3DSurface9_Release(surf2);
9250 IDirect3DSurface9_Release(backbuf);
9251 IDirect3DSurface9_Release(readback);
9254 struct formats {
9255 const char *fmtName;
9256 D3DFORMAT textureFormat;
9257 DWORD resultColorBlending;
9258 DWORD resultColorNoBlending;
9261 static const struct formats test_formats[] = {
9262 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9263 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9264 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9265 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9266 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9267 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9268 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9269 { NULL, 0 }
9272 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9274 HRESULT hr;
9275 IDirect3DTexture9 *offscreenTexture = NULL;
9276 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9277 IDirect3D9 *d3d = NULL;
9278 DWORD color;
9279 DWORD r0, g0, b0, r1, g1, b1;
9280 int fmt_index;
9282 static const float quad[][5] = {
9283 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9284 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9285 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9286 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9289 /* Quad with R=0x10, G=0x20 */
9290 static const struct vertex quad1[] = {
9291 {-1.0f, -1.0f, 0.1f, 0x80102000},
9292 {-1.0f, 1.0f, 0.1f, 0x80102000},
9293 { 1.0f, -1.0f, 0.1f, 0x80102000},
9294 { 1.0f, 1.0f, 0.1f, 0x80102000},
9297 /* Quad with R=0x20, G=0x10 */
9298 static const struct vertex quad2[] = {
9299 {-1.0f, -1.0f, 0.1f, 0x80201000},
9300 {-1.0f, 1.0f, 0.1f, 0x80201000},
9301 { 1.0f, -1.0f, 0.1f, 0x80201000},
9302 { 1.0f, 1.0f, 0.1f, 0x80201000},
9305 IDirect3DDevice9_GetDirect3D(device, &d3d);
9307 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9308 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9309 if(!backbuffer) {
9310 goto out;
9313 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9315 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9317 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9318 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9320 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9321 continue;
9324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9325 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9327 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9328 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9329 if(!offscreenTexture) {
9330 continue;
9333 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9334 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9335 if(!offscreen) {
9336 continue;
9339 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9340 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9342 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9343 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9344 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9345 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9346 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9347 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9348 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9349 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9353 /* Below we will draw two quads with different colors and try to blend them together.
9354 * The result color is compared with the expected outcome.
9356 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9357 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9358 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9359 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9360 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9363 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9365 /* Draw a quad using color 0x0010200 */
9366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9369 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9370 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9371 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9373 /* Draw a quad using color 0x0020100 */
9374 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9375 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9377 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9379 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9381 /* We don't want to blend the result on the backbuffer */
9382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9383 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9385 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9386 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9387 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9388 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9389 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9392 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9394 /* This time with the texture */
9395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9396 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9398 IDirect3DDevice9_EndScene(device);
9401 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9402 /* Compare the color of the center quad with our expectation */
9403 color = getPixelColor(device, 320, 240);
9404 r0 = (color & 0x00ff0000) >> 16;
9405 g0 = (color & 0x0000ff00) >> 8;
9406 b0 = (color & 0x000000ff) >> 0;
9408 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9409 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9410 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9412 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9413 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9414 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9415 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9416 } else {
9417 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9418 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9419 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9420 color = getPixelColor(device, 320, 240);
9421 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);
9423 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9425 IDirect3DDevice9_SetTexture(device, 0, NULL);
9426 if(offscreenTexture) {
9427 IDirect3DTexture9_Release(offscreenTexture);
9429 if(offscreen) {
9430 IDirect3DSurface9_Release(offscreen);
9434 out:
9435 /* restore things */
9436 if(backbuffer) {
9437 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9438 IDirect3DSurface9_Release(backbuffer);
9442 static void tssargtemp_test(IDirect3DDevice9 *device)
9444 HRESULT hr;
9445 DWORD color;
9446 static const struct vertex quad[] = {
9447 {-1.0, -1.0, 0.1, 0x00ff0000},
9448 { 1.0, -1.0, 0.1, 0x00ff0000},
9449 {-1.0, 1.0, 0.1, 0x00ff0000},
9450 { 1.0, 1.0, 0.1, 0x00ff0000}
9452 D3DCAPS9 caps;
9454 memset(&caps, 0, sizeof(caps));
9455 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9456 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9457 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9458 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9459 return;
9462 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9463 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9465 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9466 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9467 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9468 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9470 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9471 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9472 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9473 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9474 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9475 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9477 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9478 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9479 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9480 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9481 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9482 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9484 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9485 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9488 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9490 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9492 hr = IDirect3DDevice9_BeginScene(device);
9493 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9494 if(SUCCEEDED(hr)) {
9495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9496 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9497 hr = IDirect3DDevice9_EndScene(device);
9498 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9500 color = getPixelColor(device, 320, 240);
9501 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9502 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9504 /* Set stage 1 back to default */
9505 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9506 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9507 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9508 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9509 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9510 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9511 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9512 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9513 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9514 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9517 struct testdata
9519 DWORD idxVertex; /* number of instances in the first stream */
9520 DWORD idxColor; /* number of instances in the second stream */
9521 DWORD idxInstance; /* should be 1 ?? */
9522 DWORD color1; /* color 1 instance */
9523 DWORD color2; /* color 2 instance */
9524 DWORD color3; /* color 3 instance */
9525 DWORD color4; /* color 4 instance */
9526 WORD strVertex; /* specify which stream to use 0-2*/
9527 WORD strColor;
9528 WORD strInstance;
9531 static const struct testdata testcases[]=
9533 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9534 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9535 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9536 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9537 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9538 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9539 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9540 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9541 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9542 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9543 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9544 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9545 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9546 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9548 This draws one instance on some machines, no instance on others
9549 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9552 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9553 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9557 /* Drawing Indexed Geometry with instances*/
9558 static void stream_test(IDirect3DDevice9 *device)
9560 IDirect3DVertexBuffer9 *vb = NULL;
9561 IDirect3DVertexBuffer9 *vb2 = NULL;
9562 IDirect3DVertexBuffer9 *vb3 = NULL;
9563 IDirect3DIndexBuffer9 *ib = NULL;
9564 IDirect3DVertexDeclaration9 *pDecl = NULL;
9565 IDirect3DVertexShader9 *shader = NULL;
9566 HRESULT hr;
9567 BYTE *data;
9568 DWORD color;
9569 DWORD ind;
9570 unsigned i;
9572 const DWORD shader_code[] =
9574 0xfffe0101, /* vs_1_1 */
9575 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9576 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9577 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9578 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9579 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9580 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9581 0x0000ffff
9584 const float quad[][3] =
9586 {-0.5f, -0.5f, 1.1f}, /*0 */
9587 {-0.5f, 0.5f, 1.1f}, /*1 */
9588 { 0.5f, -0.5f, 1.1f}, /*2 */
9589 { 0.5f, 0.5f, 1.1f}, /*3 */
9592 const float vertcolor[][4] =
9594 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9595 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9596 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9597 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9600 /* 4 position for 4 instances */
9601 const float instancepos[][3] =
9603 {-0.6f,-0.6f, 0.0f},
9604 { 0.6f,-0.6f, 0.0f},
9605 { 0.6f, 0.6f, 0.0f},
9606 {-0.6f, 0.6f, 0.0f},
9609 short indices[] = {0, 1, 2, 1, 2, 3};
9611 D3DVERTEXELEMENT9 decl[] =
9613 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9614 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9615 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9616 D3DDECL_END()
9619 /* set the default value because it isn't done in wine? */
9620 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9621 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9623 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9624 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9625 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9627 /* check wrong cases */
9628 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9629 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9630 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9631 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9632 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9633 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9634 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9635 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9636 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9637 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9638 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9639 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9640 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9641 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9642 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9643 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9644 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9645 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9646 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9647 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9649 /* set the default value back */
9650 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9651 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9653 /* create all VertexBuffers*/
9654 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9655 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9656 if(!vb) {
9657 skip("Failed to create a vertex buffer\n");
9658 return;
9660 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9661 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9662 if(!vb2) {
9663 skip("Failed to create a vertex buffer\n");
9664 goto out;
9666 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9667 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9668 if(!vb3) {
9669 skip("Failed to create a vertex buffer\n");
9670 goto out;
9673 /* create IndexBuffer*/
9674 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9675 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9676 if(!ib) {
9677 skip("Failed to create a index buffer\n");
9678 goto out;
9681 /* copy all Buffers (Vertex + Index)*/
9682 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9683 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9684 memcpy(data, quad, sizeof(quad));
9685 hr = IDirect3DVertexBuffer9_Unlock(vb);
9686 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9687 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9688 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9689 memcpy(data, vertcolor, sizeof(vertcolor));
9690 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9691 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9692 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9693 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9694 memcpy(data, instancepos, sizeof(instancepos));
9695 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9696 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9697 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9698 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9699 memcpy(data, indices, sizeof(indices));
9700 hr = IDirect3DIndexBuffer9_Unlock(ib);
9701 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9703 /* create VertexShader */
9704 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9705 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9706 if(!shader) {
9707 skip("Failed to create a vetex shader\n");
9708 goto out;
9711 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9712 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9714 hr = IDirect3DDevice9_SetIndices(device, ib);
9715 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9717 /* run all tests */
9718 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9720 struct testdata act = testcases[i];
9721 decl[0].Stream = act.strVertex;
9722 decl[1].Stream = act.strColor;
9723 decl[2].Stream = act.strInstance;
9724 /* create VertexDeclarations */
9725 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9726 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9728 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9729 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9731 hr = IDirect3DDevice9_BeginScene(device);
9732 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9733 if(SUCCEEDED(hr))
9735 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9736 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9738 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9739 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9740 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9741 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9743 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9744 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9745 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9746 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9748 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9749 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9750 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9751 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9753 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9754 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9755 hr = IDirect3DDevice9_EndScene(device);
9756 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9758 /* set all StreamSource && StreamSourceFreq back to default */
9759 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9760 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9761 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9762 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9763 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9764 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9765 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9766 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9767 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9768 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9769 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9770 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9773 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9774 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9776 color = getPixelColor(device, 160, 360);
9777 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9778 color = getPixelColor(device, 480, 360);
9779 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9780 color = getPixelColor(device, 480, 120);
9781 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9782 color = getPixelColor(device, 160, 120);
9783 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9785 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9786 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9789 hr = IDirect3DDevice9_SetIndices(device, NULL);
9790 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9792 out:
9793 if(vb) IDirect3DVertexBuffer9_Release(vb);
9794 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9795 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9796 if(ib)IDirect3DIndexBuffer9_Release(ib);
9797 if(shader)IDirect3DVertexShader9_Release(shader);
9800 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9801 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9802 IDirect3DTexture9 *dsttex = NULL;
9803 HRESULT hr;
9804 DWORD color;
9805 D3DRECT r1 = {0, 0, 50, 50 };
9806 D3DRECT r2 = {50, 0, 100, 50 };
9807 D3DRECT r3 = {50, 50, 100, 100};
9808 D3DRECT r4 = {0, 50, 50, 100};
9809 const float quad[] = {
9810 -1.0, -1.0, 0.1, 0.0, 0.0,
9811 1.0, -1.0, 0.1, 1.0, 0.0,
9812 -1.0, 1.0, 0.1, 0.0, 1.0,
9813 1.0, 1.0, 0.1, 1.0, 1.0,
9816 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9817 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9819 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9820 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9821 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9822 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9824 if(!src || !dsttex) {
9825 skip("One or more test resources could not be created\n");
9826 goto cleanup;
9829 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9830 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9832 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9833 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9835 /* Clear the StretchRect destination for debugging */
9836 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9837 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9839 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9841 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9842 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9844 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9845 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9846 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9847 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9848 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9849 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9850 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9851 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9853 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9854 * the target -> texture GL blit path
9856 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9857 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9858 IDirect3DSurface9_Release(dst);
9860 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9861 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9863 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9864 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9865 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9866 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9867 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9868 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9869 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9870 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9872 hr = IDirect3DDevice9_BeginScene(device);
9873 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9874 if(SUCCEEDED(hr)) {
9875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9876 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9877 hr = IDirect3DDevice9_EndScene(device);
9878 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9881 color = getPixelColor(device, 160, 360);
9882 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9883 color = getPixelColor(device, 480, 360);
9884 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9885 color = getPixelColor(device, 480, 120);
9886 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9887 color = getPixelColor(device, 160, 120);
9888 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9889 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9890 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9892 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9893 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9894 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9895 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9897 cleanup:
9898 if(src) IDirect3DSurface9_Release(src);
9899 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9900 if(dsttex) IDirect3DTexture9_Release(dsttex);
9903 static void texop_test(IDirect3DDevice9 *device)
9905 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9906 IDirect3DTexture9 *texture = NULL;
9907 D3DLOCKED_RECT locked_rect;
9908 D3DCOLOR color;
9909 D3DCAPS9 caps;
9910 HRESULT hr;
9911 unsigned i;
9913 static const struct {
9914 float x, y, z;
9915 float s, t;
9916 D3DCOLOR diffuse;
9917 } quad[] = {
9918 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9919 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9920 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9921 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9924 static const D3DVERTEXELEMENT9 decl_elements[] = {
9925 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9926 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9927 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9928 D3DDECL_END()
9931 static const struct {
9932 D3DTEXTUREOP op;
9933 const char *name;
9934 DWORD caps_flag;
9935 D3DCOLOR result;
9936 } test_data[] = {
9937 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9938 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9939 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9940 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9941 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9942 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9943 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9944 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9945 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9946 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9947 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9948 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9949 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9950 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9951 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9952 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9953 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9954 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9955 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9956 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9957 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9958 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9959 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9962 memset(&caps, 0, sizeof(caps));
9963 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9964 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9966 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9967 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9968 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9969 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9971 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9972 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9973 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9974 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9975 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9976 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9977 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9978 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9979 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9981 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9982 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9983 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9984 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9985 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9986 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9988 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9989 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9992 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9994 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9996 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9998 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9999 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10001 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10003 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10005 skip("tex operation %s not supported\n", test_data[i].name);
10006 continue;
10009 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10010 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10012 hr = IDirect3DDevice9_BeginScene(device);
10013 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10016 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10018 hr = IDirect3DDevice9_EndScene(device);
10019 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10021 color = getPixelColor(device, 320, 240);
10022 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10023 test_data[i].name, color, test_data[i].result);
10025 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10026 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10029 if (texture) IDirect3DTexture9_Release(texture);
10030 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10033 static void yuv_color_test(IDirect3DDevice9 *device) {
10034 HRESULT hr;
10035 IDirect3DSurface9 *surface = NULL, *target = NULL;
10036 unsigned int fmt, i;
10037 D3DFORMAT format;
10038 const char *fmt_string;
10039 D3DLOCKED_RECT lr;
10040 IDirect3D9 *d3d;
10041 HRESULT color;
10042 DWORD ref_color_left, ref_color_right;
10044 struct {
10045 DWORD in; /* The input color */
10046 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10047 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10048 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10049 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10050 } test_data[] = {
10051 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10052 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10053 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10054 * that
10056 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10057 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10058 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10059 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10060 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10061 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10062 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10063 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10064 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10065 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10066 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10067 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10068 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10069 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10071 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10072 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10073 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10074 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10077 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10078 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10079 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10080 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10082 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10083 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10085 for(fmt = 0; fmt < 2; fmt++) {
10086 if(fmt == 0) {
10087 format = D3DFMT_UYVY;
10088 fmt_string = "D3DFMT_UYVY";
10089 } else {
10090 format = D3DFMT_YUY2;
10091 fmt_string = "D3DFMT_YUY2";
10094 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10095 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10097 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10098 D3DRTYPE_SURFACE, format) != D3D_OK) {
10099 skip("%s is not supported\n", fmt_string);
10100 continue;
10103 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10104 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10105 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10107 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10108 if(fmt == 0) {
10109 ref_color_left = test_data[i].uyvy_left;
10110 ref_color_right = test_data[i].uyvy_right;
10111 } else {
10112 ref_color_left = test_data[i].yuy2_left;
10113 ref_color_right = test_data[i].yuy2_right;
10116 memset(&lr, 0, sizeof(lr));
10117 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10118 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10119 *((DWORD *) lr.pBits) = test_data[i].in;
10120 hr = IDirect3DSurface9_UnlockRect(surface);
10121 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10123 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10124 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10125 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10126 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10128 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10129 * prevent running into precision problems, read a far left and far right pixel. In the future we may
10130 * want to add tests for the filtered pixels as well.
10132 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10133 * differently, so we need a max diff of 16
10135 color = getPixelColor(device, 40, 240);
10137 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10138 * where U != V. Skip the entire test if this bug in this case
10140 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10142 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10143 IDirect3DSurface9_Release(surface);
10144 goto out;
10147 ok(color_match(color, ref_color_left, 18),
10148 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10149 test_data[i].in, color, ref_color_left, fmt_string);
10150 color = getPixelColor(device, 600, 240);
10151 ok(color_match(color, ref_color_right, 18),
10152 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10153 test_data[i].in, color, ref_color_right, fmt_string);
10154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10155 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10157 IDirect3DSurface9_Release(surface);
10160 out:
10161 IDirect3DSurface9_Release(target);
10162 IDirect3D9_Release(d3d);
10165 static void texop_range_test(IDirect3DDevice9 *device)
10167 static const struct {
10168 float x, y, z;
10169 D3DCOLOR diffuse;
10170 } quad[] = {
10171 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10172 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10173 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10174 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10176 HRESULT hr;
10177 IDirect3DTexture9 *texture;
10178 D3DLOCKED_RECT locked_rect;
10179 D3DCAPS9 caps;
10180 DWORD color;
10182 /* We need ADD and SUBTRACT operations */
10183 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10184 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10185 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10186 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10187 return;
10189 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10190 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10191 return;
10194 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10195 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10196 /* Stage 1: result = diffuse(=1.0) + diffuse
10197 * stage 2: result = result - tfactor(= 0.5)
10199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10200 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10201 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10202 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10203 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10204 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10205 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10206 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10207 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10208 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10209 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10210 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10211 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10212 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10214 hr = IDirect3DDevice9_BeginScene(device);
10215 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10217 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10218 hr = IDirect3DDevice9_EndScene(device);
10219 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10221 color = getPixelColor(device, 320, 240);
10222 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10223 color);
10224 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10225 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10227 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10228 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10229 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10230 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10231 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10232 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10233 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10234 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10235 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10237 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10238 * stage 2: result = result + diffuse(1.0)
10240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10241 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10242 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10243 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10244 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10245 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10246 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10247 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10248 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10249 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10250 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10251 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10252 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10253 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10255 hr = IDirect3DDevice9_BeginScene(device);
10256 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10258 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10259 hr = IDirect3DDevice9_EndScene(device);
10260 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10262 color = getPixelColor(device, 320, 240);
10263 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10264 color);
10265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10266 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10268 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10269 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10270 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10271 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10272 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10273 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10274 IDirect3DTexture9_Release(texture);
10277 static void alphareplicate_test(IDirect3DDevice9 *device) {
10278 struct vertex quad[] = {
10279 { -1.0, -1.0, 0.1, 0x80ff00ff },
10280 { 1.0, -1.0, 0.1, 0x80ff00ff },
10281 { -1.0, 1.0, 0.1, 0x80ff00ff },
10282 { 1.0, 1.0, 0.1, 0x80ff00ff },
10284 HRESULT hr;
10285 DWORD color;
10287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10288 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10290 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10291 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10293 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10294 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10295 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10296 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10298 hr = IDirect3DDevice9_BeginScene(device);
10299 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10300 if(SUCCEEDED(hr)) {
10301 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10302 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10303 hr = IDirect3DDevice9_EndScene(device);
10304 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10307 color = getPixelColor(device, 320, 240);
10308 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10309 color);
10310 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10311 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10313 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10314 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10318 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10319 HRESULT hr;
10320 D3DCAPS9 caps;
10321 DWORD color;
10322 struct vertex quad[] = {
10323 { -1.0, -1.0, 0.1, 0x408080c0 },
10324 { 1.0, -1.0, 0.1, 0x408080c0 },
10325 { -1.0, 1.0, 0.1, 0x408080c0 },
10326 { 1.0, 1.0, 0.1, 0x408080c0 },
10329 memset(&caps, 0, sizeof(caps));
10330 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10331 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10332 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10333 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10334 return;
10337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10338 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10340 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10341 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10343 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10344 * mov r0.a, diffuse.a
10345 * mov r0, r0.a
10347 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10348 * 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
10349 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10351 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10352 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10353 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10354 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10356 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10357 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10358 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10359 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10360 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10361 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10362 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10363 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10364 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10365 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10366 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10368 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10370 hr = IDirect3DDevice9_BeginScene(device);
10371 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10372 if(SUCCEEDED(hr)) {
10373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10374 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10375 hr = IDirect3DDevice9_EndScene(device);
10376 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10379 color = getPixelColor(device, 320, 240);
10380 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10381 color);
10382 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10383 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10385 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10387 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10388 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10389 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10390 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10393 static void zwriteenable_test(IDirect3DDevice9 *device) {
10394 HRESULT hr;
10395 DWORD color;
10396 struct vertex quad1[] = {
10397 { -1.0, -1.0, 0.1, 0x00ff0000},
10398 { -1.0, 1.0, 0.1, 0x00ff0000},
10399 { 1.0, -1.0, 0.1, 0x00ff0000},
10400 { 1.0, 1.0, 0.1, 0x00ff0000},
10402 struct vertex quad2[] = {
10403 { -1.0, -1.0, 0.9, 0x0000ff00},
10404 { -1.0, 1.0, 0.9, 0x0000ff00},
10405 { 1.0, -1.0, 0.9, 0x0000ff00},
10406 { 1.0, 1.0, 0.9, 0x0000ff00},
10409 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10410 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10412 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10413 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10414 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10415 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10417 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10419 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10421 hr = IDirect3DDevice9_BeginScene(device);
10422 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10423 if(SUCCEEDED(hr)) {
10424 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10425 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10426 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10427 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10428 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10429 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10431 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10432 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10433 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10434 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10436 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10438 hr = IDirect3DDevice9_EndScene(device);
10439 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10442 color = getPixelColor(device, 320, 240);
10443 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10444 color);
10445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10446 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10449 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10452 static void alphatest_test(IDirect3DDevice9 *device) {
10453 #define ALPHATEST_PASSED 0x0000ff00
10454 #define ALPHATEST_FAILED 0x00ff0000
10455 struct {
10456 D3DCMPFUNC func;
10457 DWORD color_less;
10458 DWORD color_equal;
10459 DWORD color_greater;
10460 } testdata[] = {
10461 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10462 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10463 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10464 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10465 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10466 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10467 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10468 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10470 unsigned int i, j;
10471 HRESULT hr;
10472 DWORD color;
10473 struct vertex quad[] = {
10474 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10475 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10476 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10477 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10479 D3DCAPS9 caps;
10481 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10482 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10483 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10484 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10486 for(j = 0; j < 2; j++) {
10487 if(j == 1) {
10488 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10489 * the alpha test either for performance reasons(floating point RTs) or to work
10490 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10491 * codepath for ffp and shader in this case, and the test should cover both
10493 IDirect3DPixelShader9 *ps;
10494 DWORD shader_code[] = {
10495 0xffff0101, /* ps_1_1 */
10496 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10497 0x0000ffff /* end */
10499 memset(&caps, 0, sizeof(caps));
10500 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10501 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10502 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10503 break;
10506 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10507 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10508 IDirect3DDevice9_SetPixelShader(device, ps);
10509 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10510 IDirect3DPixelShader9_Release(ps);
10513 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10515 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10518 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10520 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10521 hr = IDirect3DDevice9_BeginScene(device);
10522 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10523 if(SUCCEEDED(hr)) {
10524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10525 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10526 hr = IDirect3DDevice9_EndScene(device);
10527 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10529 color = getPixelColor(device, 320, 240);
10530 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10531 color, testdata[i].color_less, testdata[i].func);
10532 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10533 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10536 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10538 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10539 hr = IDirect3DDevice9_BeginScene(device);
10540 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10541 if(SUCCEEDED(hr)) {
10542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10543 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10544 hr = IDirect3DDevice9_EndScene(device);
10545 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10547 color = getPixelColor(device, 320, 240);
10548 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10549 color, testdata[i].color_equal, testdata[i].func);
10550 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10551 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10553 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10554 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10556 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10557 hr = IDirect3DDevice9_BeginScene(device);
10558 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10559 if(SUCCEEDED(hr)) {
10560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10561 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10562 hr = IDirect3DDevice9_EndScene(device);
10563 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10565 color = getPixelColor(device, 320, 240);
10566 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10567 color, testdata[i].color_greater, testdata[i].func);
10568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10569 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10574 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10575 IDirect3DDevice9_SetPixelShader(device, NULL);
10576 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10579 static void sincos_test(IDirect3DDevice9 *device) {
10580 const DWORD sin_shader_code[] = {
10581 0xfffe0200, /* vs_2_0 */
10582 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10583 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10584 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10585 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10586 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10587 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10588 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10589 0x0000ffff /* end */
10591 const DWORD cos_shader_code[] = {
10592 0xfffe0200, /* vs_2_0 */
10593 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10594 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10595 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10596 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10597 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10598 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10599 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10600 0x0000ffff /* end */
10602 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10603 HRESULT hr;
10604 struct {
10605 float x, y, z;
10606 } data[1280];
10607 unsigned int i;
10608 float sincosc1[4] = {D3DSINCOSCONST1};
10609 float sincosc2[4] = {D3DSINCOSCONST2};
10611 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10612 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10614 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10615 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10616 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10618 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10619 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10620 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10621 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10622 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10623 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10625 /* Generate a point from -1 to 1 every 0.5 pixels */
10626 for(i = 0; i < 1280; i++) {
10627 data[i].x = (-640.0 + i) / 640.0;
10628 data[i].y = 0.0;
10629 data[i].z = 0.1;
10632 hr = IDirect3DDevice9_BeginScene(device);
10633 if(SUCCEEDED(hr)) {
10634 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10635 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10637 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10639 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10640 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10642 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10644 hr = IDirect3DDevice9_EndScene(device);
10645 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10648 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10649 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10651 IDirect3DDevice9_SetVertexShader(device, NULL);
10652 IDirect3DVertexShader9_Release(sin_shader);
10653 IDirect3DVertexShader9_Release(cos_shader);
10656 static void loop_index_test(IDirect3DDevice9 *device) {
10657 const DWORD shader_code[] = {
10658 0xfffe0200, /* vs_2_0 */
10659 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10660 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10661 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10662 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10663 0x0000001d, /* endloop */
10664 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10665 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10666 0x0000ffff /* END */
10668 IDirect3DVertexShader9 *shader;
10669 HRESULT hr;
10670 DWORD color;
10671 const float quad[] = {
10672 -1.0, -1.0, 0.1,
10673 1.0, -1.0, 0.1,
10674 -1.0, 1.0, 0.1,
10675 1.0, 1.0, 0.1
10677 const float zero[4] = {0, 0, 0, 0};
10678 const float one[4] = {1, 1, 1, 1};
10679 int i0[4] = {2, 10, -3, 0};
10680 float values[4];
10682 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10683 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10684 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10685 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10686 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10687 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10689 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10691 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10692 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10693 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10694 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10695 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10696 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10697 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10698 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10699 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10700 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10701 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10702 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10703 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10704 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10705 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10706 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10707 values[0] = 1.0;
10708 values[1] = 1.0;
10709 values[2] = 0.0;
10710 values[3] = 0.0;
10711 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10712 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10713 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10714 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10715 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10716 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10717 values[0] = -1.0;
10718 values[1] = 0.0;
10719 values[2] = 0.0;
10720 values[3] = 0.0;
10721 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10722 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10723 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10724 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10725 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10726 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10727 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10728 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10729 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10730 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10732 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10733 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10735 hr = IDirect3DDevice9_BeginScene(device);
10736 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10737 if(SUCCEEDED(hr))
10739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10740 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10741 hr = IDirect3DDevice9_EndScene(device);
10742 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10744 color = getPixelColor(device, 320, 240);
10745 ok(color_match(color, 0x0000ff00, 1),
10746 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10747 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10748 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10750 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10751 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10752 IDirect3DVertexShader9_Release(shader);
10755 static void sgn_test(IDirect3DDevice9 *device) {
10756 const DWORD shader_code[] = {
10757 0xfffe0200, /* vs_2_0 */
10758 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10759 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10760 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10761 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10762 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10763 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10764 0x0000ffff /* end */
10766 IDirect3DVertexShader9 *shader;
10767 HRESULT hr;
10768 DWORD color;
10769 const float quad[] = {
10770 -1.0, -1.0, 0.1,
10771 1.0, -1.0, 0.1,
10772 -1.0, 1.0, 0.1,
10773 1.0, 1.0, 0.1
10776 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10777 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10778 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10779 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10780 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10781 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10782 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10783 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10785 hr = IDirect3DDevice9_BeginScene(device);
10786 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10787 if(SUCCEEDED(hr))
10789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10791 hr = IDirect3DDevice9_EndScene(device);
10792 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10794 color = getPixelColor(device, 320, 240);
10795 ok(color_match(color, 0x008000ff, 1),
10796 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10798 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10800 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10801 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10802 IDirect3DVertexShader9_Release(shader);
10805 static void viewport_test(IDirect3DDevice9 *device) {
10806 HRESULT hr;
10807 DWORD color;
10808 D3DVIEWPORT9 vp, old_vp;
10809 BOOL draw_failed = TRUE;
10810 const float quad[] =
10812 -0.5, -0.5, 0.1,
10813 0.5, -0.5, 0.1,
10814 -0.5, 0.5, 0.1,
10815 0.5, 0.5, 0.1
10818 memset(&old_vp, 0, sizeof(old_vp));
10819 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10820 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10822 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10823 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10825 /* Test a viewport with Width and Height bigger than the surface dimensions
10827 * TODO: Test Width < surface.width, but X + Width > surface.width
10828 * TODO: Test Width < surface.width, what happens with the height?
10830 * The expected behavior is that the viewport behaves like the "default"
10831 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10832 * MinZ = 0.0, MaxZ = 1.0.
10834 * Starting with Windows 7 the behavior among driver versions is not
10835 * consistent. The SetViewport call is accepted on all drivers. Some
10836 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10837 * nvidia drivers draw, but use the actual values in the viewport and only
10838 * display the upper left part on the surface.
10840 memset(&vp, 0, sizeof(vp));
10841 vp.X = 0;
10842 vp.Y = 0;
10843 vp.Width = 10000;
10844 vp.Height = 10000;
10845 vp.MinZ = 0.0;
10846 vp.MaxZ = 0.0;
10847 hr = IDirect3DDevice9_SetViewport(device, &vp);
10848 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10850 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10851 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10852 hr = IDirect3DDevice9_BeginScene(device);
10853 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10854 if(SUCCEEDED(hr))
10856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10857 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10858 draw_failed = FAILED(hr);
10859 hr = IDirect3DDevice9_EndScene(device);
10860 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10863 if(!draw_failed)
10865 color = getPixelColor(device, 158, 118);
10866 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10867 color = getPixelColor(device, 162, 118);
10868 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10869 color = getPixelColor(device, 158, 122);
10870 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10871 color = getPixelColor(device, 162, 122);
10872 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10874 color = getPixelColor(device, 478, 358);
10875 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10876 color = getPixelColor(device, 482, 358);
10877 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10878 color = getPixelColor(device, 478, 362);
10879 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10880 color = getPixelColor(device, 482, 362);
10881 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10885 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10887 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10888 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10891 /* This test tests depth clamping / clipping behaviour:
10892 * - With software vertex processing, depth values are clamped to the
10893 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10894 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10895 * same as regular vertices here.
10896 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10897 * Normal vertices are always clipped. Pretransformed vertices are
10898 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10899 * - The viewport's MinZ/MaxZ is irrelevant for this.
10901 static void depth_clamp_test(IDirect3DDevice9 *device)
10903 const struct tvertex quad1[] =
10905 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10906 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10907 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10908 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10910 const struct tvertex quad2[] =
10912 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10913 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10914 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10915 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10917 const struct tvertex quad3[] =
10919 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10920 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10921 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10922 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10924 const struct tvertex quad4[] =
10926 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10927 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10928 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10929 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10931 const struct vertex quad5[] =
10933 { -0.5f, 0.5f, 10.0f, 0xff14f914},
10934 { 0.5f, 0.5f, 10.0f, 0xff14f914},
10935 { -0.5f, -0.5f, 10.0f, 0xff14f914},
10936 { 0.5f, -0.5f, 10.0f, 0xff14f914},
10938 const struct vertex quad6[] =
10940 { -1.0f, 0.5f, 10.0f, 0xfff91414},
10941 { 1.0f, 0.5f, 10.0f, 0xfff91414},
10942 { -1.0f, 0.25f, 10.0f, 0xfff91414},
10943 { 1.0f, 0.25f, 10.0f, 0xfff91414},
10946 D3DVIEWPORT9 vp;
10947 D3DCOLOR color;
10948 D3DCAPS9 caps;
10949 HRESULT hr;
10951 vp.X = 0;
10952 vp.Y = 0;
10953 vp.Width = 640;
10954 vp.Height = 480;
10955 vp.MinZ = 0.0;
10956 vp.MaxZ = 7.5;
10958 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10959 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10961 hr = IDirect3DDevice9_SetViewport(device, &vp);
10962 if(FAILED(hr))
10964 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10965 * the tests because the 7.5 is just intended to show that it doesn't have
10966 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10967 * viewport and continue.
10969 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10970 vp.MaxZ = 1.0;
10971 hr = IDirect3DDevice9_SetViewport(device, &vp);
10973 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10976 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10979 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10981 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10983 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10985 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10987 hr = IDirect3DDevice9_BeginScene(device);
10988 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10990 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10991 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10994 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10996 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10999 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11002 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11004 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11006 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11007 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11009 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11010 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11012 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11013 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11016 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11018 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11019 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11021 hr = IDirect3DDevice9_EndScene(device);
11022 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11024 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11026 color = getPixelColor(device, 75, 75);
11027 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11028 color = getPixelColor(device, 150, 150);
11029 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11030 color = getPixelColor(device, 320, 240);
11031 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11032 color = getPixelColor(device, 320, 330);
11033 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11034 color = getPixelColor(device, 320, 330);
11035 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11037 else
11039 color = getPixelColor(device, 75, 75);
11040 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11041 color = getPixelColor(device, 150, 150);
11042 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11043 color = getPixelColor(device, 320, 240);
11044 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11045 color = getPixelColor(device, 320, 330);
11046 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11047 color = getPixelColor(device, 320, 330);
11048 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11052 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11054 vp.MinZ = 0.0;
11055 vp.MaxZ = 1.0;
11056 hr = IDirect3DDevice9_SetViewport(device, &vp);
11057 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11060 static void depth_bounds_test(IDirect3DDevice9 *device)
11062 const struct tvertex quad1[] =
11064 { 0, 0, 0.0f, 1, 0xfff9e814},
11065 { 640, 0, 0.0f, 1, 0xfff9e814},
11066 { 0, 480, 1.0f, 1, 0xfff9e814},
11067 { 640, 480, 1.0f, 1, 0xfff9e814},
11069 const struct tvertex quad2[] =
11071 { 0, 0, 0.6f, 1, 0xff002b7f},
11072 { 640, 0, 0.6f, 1, 0xff002b7f},
11073 { 0, 480, 0.6f, 1, 0xff002b7f},
11074 { 640, 480, 0.6f, 1, 0xff002b7f},
11076 const struct tvertex quad3[] =
11078 { 0, 100, 0.6f, 1, 0xfff91414},
11079 { 640, 100, 0.6f, 1, 0xfff91414},
11080 { 0, 160, 0.6f, 1, 0xfff91414},
11081 { 640, 160, 0.6f, 1, 0xfff91414},
11084 union {
11085 DWORD d;
11086 float f;
11087 } tmpvalue;
11089 IDirect3D9 *d3d = NULL;
11090 IDirect3DSurface9 *offscreen_surface = NULL;
11091 D3DCOLOR color;
11092 HRESULT hr;
11094 IDirect3DDevice9_GetDirect3D(device, &d3d);
11095 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11096 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11097 skip("No NVDB (depth bounds test) support\n");
11098 IDirect3D9_Release(d3d);
11099 return;
11101 IDirect3D9_Release(d3d);
11103 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11104 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11105 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11106 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11108 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11109 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11112 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11114 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11116 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11118 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11121 hr = IDirect3DDevice9_BeginScene(device);
11122 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11124 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11125 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11128 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11131 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11133 tmpvalue.f = 0.625;
11134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11135 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11137 tmpvalue.f = 0.75;
11138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11139 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11141 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11142 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11144 tmpvalue.f = 0.75;
11145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11146 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11149 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11152 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_EndScene(device);
11155 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11157 color = getPixelColor(device, 150, 130);
11158 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11159 color = getPixelColor(device, 150, 200);
11160 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11161 color = getPixelColor(device, 150, 300-5);
11162 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11163 color = getPixelColor(device, 150, 300+5);
11164 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11165 color = getPixelColor(device, 150, 330);
11166 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11167 color = getPixelColor(device, 150, 360-5);
11168 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11169 color = getPixelColor(device, 150, 360+5);
11170 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11173 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11176 static void depth_buffer_test(IDirect3DDevice9 *device)
11178 static const struct vertex quad1[] =
11180 { -1.0, 1.0, 0.33f, 0xff00ff00},
11181 { 1.0, 1.0, 0.33f, 0xff00ff00},
11182 { -1.0, -1.0, 0.33f, 0xff00ff00},
11183 { 1.0, -1.0, 0.33f, 0xff00ff00},
11185 static const struct vertex quad2[] =
11187 { -1.0, 1.0, 0.50f, 0xffff00ff},
11188 { 1.0, 1.0, 0.50f, 0xffff00ff},
11189 { -1.0, -1.0, 0.50f, 0xffff00ff},
11190 { 1.0, -1.0, 0.50f, 0xffff00ff},
11192 static const struct vertex quad3[] =
11194 { -1.0, 1.0, 0.66f, 0xffff0000},
11195 { 1.0, 1.0, 0.66f, 0xffff0000},
11196 { -1.0, -1.0, 0.66f, 0xffff0000},
11197 { 1.0, -1.0, 0.66f, 0xffff0000},
11199 static const DWORD expected_colors[4][4] =
11201 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11202 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11203 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11204 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11207 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11208 unsigned int i, j;
11209 D3DVIEWPORT9 vp;
11210 D3DCOLOR color;
11211 HRESULT hr;
11213 vp.X = 0;
11214 vp.Y = 0;
11215 vp.Width = 640;
11216 vp.Height = 480;
11217 vp.MinZ = 0.0;
11218 vp.MaxZ = 1.0;
11220 hr = IDirect3DDevice9_SetViewport(device, &vp);
11221 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11224 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11226 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11228 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11230 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11231 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11232 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11234 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11235 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11236 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11237 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11238 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11239 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11240 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11241 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11242 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11243 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11244 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11246 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11247 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11249 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11251 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11252 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11253 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11254 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11256 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11257 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11258 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11259 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11261 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11262 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11263 hr = IDirect3DDevice9_BeginScene(device);
11264 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11266 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11267 hr = IDirect3DDevice9_EndScene(device);
11268 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11270 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11271 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11272 IDirect3DSurface9_Release(backbuffer);
11273 IDirect3DSurface9_Release(rt3);
11274 IDirect3DSurface9_Release(rt2);
11275 IDirect3DSurface9_Release(rt1);
11277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11278 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11280 hr = IDirect3DDevice9_BeginScene(device);
11281 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11283 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11285 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11286 hr = IDirect3DDevice9_EndScene(device);
11287 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11289 for (i = 0; i < 4; ++i)
11291 for (j = 0; j < 4; ++j)
11293 unsigned int x = 80 * ((2 * j) + 1);
11294 unsigned int y = 60 * ((2 * i) + 1);
11295 color = getPixelColor(device, x, y);
11296 ok(color_match(color, expected_colors[i][j], 0),
11297 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11301 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11302 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11305 /* Test that partial depth copies work the way they're supposed to. The clear
11306 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11307 * the following draw should only copy back the part that was modified. */
11308 static void depth_buffer2_test(IDirect3DDevice9 *device)
11310 static const struct vertex quad[] =
11312 { -1.0, 1.0, 0.66f, 0xffff0000},
11313 { 1.0, 1.0, 0.66f, 0xffff0000},
11314 { -1.0, -1.0, 0.66f, 0xffff0000},
11315 { 1.0, -1.0, 0.66f, 0xffff0000},
11318 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11319 unsigned int i, j;
11320 D3DVIEWPORT9 vp;
11321 D3DCOLOR color;
11322 HRESULT hr;
11324 vp.X = 0;
11325 vp.Y = 0;
11326 vp.Width = 640;
11327 vp.Height = 480;
11328 vp.MinZ = 0.0;
11329 vp.MaxZ = 1.0;
11331 hr = IDirect3DDevice9_SetViewport(device, &vp);
11332 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11335 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11337 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11339 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11341 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11342 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11343 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11345 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11346 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11347 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11348 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11349 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11350 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11351 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11352 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11354 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11355 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11357 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11359 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11360 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11361 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11362 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11364 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11365 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11366 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11367 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11369 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11370 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11371 IDirect3DSurface9_Release(backbuffer);
11372 IDirect3DSurface9_Release(rt2);
11373 IDirect3DSurface9_Release(rt1);
11375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11376 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11378 hr = IDirect3DDevice9_BeginScene(device);
11379 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11381 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11382 hr = IDirect3DDevice9_EndScene(device);
11383 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11385 for (i = 0; i < 4; ++i)
11387 for (j = 0; j < 4; ++j)
11389 unsigned int x = 80 * ((2 * j) + 1);
11390 unsigned int y = 60 * ((2 * i) + 1);
11391 color = getPixelColor(device, x, y);
11392 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11393 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11397 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11398 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11401 static void depth_blit_test(IDirect3DDevice9 *device)
11403 static const struct vertex quad1[] =
11405 { -1.0, 1.0, 0.50f, 0xff00ff00},
11406 { 1.0, 1.0, 0.50f, 0xff00ff00},
11407 { -1.0, -1.0, 0.50f, 0xff00ff00},
11408 { 1.0, -1.0, 0.50f, 0xff00ff00},
11410 static const struct vertex quad2[] =
11412 { -1.0, 1.0, 0.66f, 0xff0000ff},
11413 { 1.0, 1.0, 0.66f, 0xff0000ff},
11414 { -1.0, -1.0, 0.66f, 0xff0000ff},
11415 { 1.0, -1.0, 0.66f, 0xff0000ff},
11417 static const DWORD expected_colors[4][4] =
11419 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11420 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11421 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11422 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11425 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11426 RECT src_rect, dst_rect;
11427 unsigned int i, j;
11428 D3DVIEWPORT9 vp;
11429 D3DCOLOR color;
11430 HRESULT hr;
11432 vp.X = 0;
11433 vp.Y = 0;
11434 vp.Width = 640;
11435 vp.Height = 480;
11436 vp.MinZ = 0.0;
11437 vp.MaxZ = 1.0;
11439 hr = IDirect3DDevice9_SetViewport(device, &vp);
11440 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11442 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11443 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11444 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11445 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11446 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11447 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11448 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11449 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11450 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11451 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11454 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11456 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11458 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11459 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11460 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11462 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11463 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11464 SetRect(&dst_rect, 0, 0, 480, 360);
11465 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11466 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11467 SetRect(&dst_rect, 0, 0, 320, 240);
11468 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11469 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11471 /* Partial blit. */
11472 SetRect(&src_rect, 0, 0, 320, 240);
11473 SetRect(&dst_rect, 0, 0, 320, 240);
11474 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11475 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11476 /* Flipped. */
11477 SetRect(&src_rect, 0, 0, 640, 480);
11478 SetRect(&dst_rect, 0, 480, 640, 0);
11479 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11480 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11481 /* Full, explicit. */
11482 SetRect(&src_rect, 0, 0, 640, 480);
11483 SetRect(&dst_rect, 0, 0, 640, 480);
11484 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11485 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11486 /* Filtered blit. */
11487 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11488 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11489 /* Depth -> color blit.*/
11490 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11491 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11492 IDirect3DSurface9_Release(backbuffer);
11493 /* Full surface, different sizes */
11494 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11495 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11496 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11497 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11499 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11500 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11501 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11502 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11503 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11504 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11505 IDirect3DSurface9_Release(ds3);
11506 IDirect3DSurface9_Release(ds2);
11507 IDirect3DSurface9_Release(ds1);
11509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11510 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11511 hr = IDirect3DDevice9_BeginScene(device);
11512 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11513 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11514 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11516 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11517 hr = IDirect3DDevice9_EndScene(device);
11518 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11520 for (i = 0; i < 4; ++i)
11522 for (j = 0; j < 4; ++j)
11524 unsigned int x = 80 * ((2 * j) + 1);
11525 unsigned int y = 60 * ((2 * i) + 1);
11526 color = getPixelColor(device, x, y);
11527 ok(color_match(color, expected_colors[i][j], 0),
11528 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11532 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11533 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11536 static void intz_test(IDirect3DDevice9 *device)
11538 static const DWORD ps_code[] =
11540 0xffff0200, /* ps_2_0 */
11541 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11542 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11543 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11544 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11545 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11546 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11547 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11548 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11549 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11550 0x0000ffff, /* end */
11552 struct
11554 float x, y, z;
11555 float s, t, p, q;
11557 quad[] =
11559 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11560 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11561 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11562 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11564 half_quad_1[] =
11566 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11567 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11568 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11569 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11571 half_quad_2[] =
11573 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11574 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11575 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11576 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11578 struct
11580 UINT x, y;
11581 D3DCOLOR color;
11583 expected_colors[] =
11585 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11586 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11587 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11588 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11589 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11590 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11591 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11592 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11595 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11596 IDirect3DTexture9 *texture;
11597 IDirect3DPixelShader9 *ps;
11598 IDirect3DSurface9 *ds;
11599 IDirect3D9 *d3d9;
11600 D3DCAPS9 caps;
11601 HRESULT hr;
11602 UINT i;
11604 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11605 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11606 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11608 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11609 return;
11611 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11613 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11614 return;
11617 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11618 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11620 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11621 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11622 if (FAILED(hr))
11624 skip("No INTZ support, skipping INTZ test.\n");
11625 return;
11628 IDirect3D9_Release(d3d9);
11630 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11631 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11632 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11633 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11635 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11636 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11637 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11638 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11639 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11640 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11641 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11642 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11644 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11645 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11647 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11649 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11651 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11653 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11655 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11656 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11657 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11658 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11659 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11660 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11661 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11662 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11663 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11664 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11666 /* Render offscreen, using the INTZ texture as depth buffer */
11667 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11668 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11669 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11670 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11671 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11672 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11673 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11674 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11676 /* Setup the depth/stencil surface. */
11677 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11678 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11680 hr = IDirect3DDevice9_BeginScene(device);
11681 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11683 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11684 hr = IDirect3DDevice9_EndScene(device);
11685 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11687 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11688 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11689 IDirect3DSurface9_Release(ds);
11690 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11691 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11692 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11693 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11694 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11695 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11697 /* Read the depth values back. */
11698 hr = IDirect3DDevice9_BeginScene(device);
11699 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11701 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11702 hr = IDirect3DDevice9_EndScene(device);
11703 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11705 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11707 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11708 ok(color_match(color, expected_colors[i].color, 1),
11709 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11710 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11713 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11714 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11716 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11717 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11718 IDirect3DTexture9_Release(texture);
11720 /* Render onscreen while using the INTZ texture as depth buffer */
11721 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11722 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11723 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11724 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11725 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11726 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11727 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11728 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11730 /* Setup the depth/stencil surface. */
11731 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11732 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11734 hr = IDirect3DDevice9_BeginScene(device);
11735 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11737 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11738 hr = IDirect3DDevice9_EndScene(device);
11739 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11741 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11742 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11743 IDirect3DSurface9_Release(ds);
11744 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11745 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11746 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11747 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11749 /* Read the depth values back. */
11750 hr = IDirect3DDevice9_BeginScene(device);
11751 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11753 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11754 hr = IDirect3DDevice9_EndScene(device);
11755 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11757 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11759 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11760 ok(color_match(color, expected_colors[i].color, 1),
11761 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11762 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11765 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11766 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11768 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11769 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11770 IDirect3DTexture9_Release(texture);
11772 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11773 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11774 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11775 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11776 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11778 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11779 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11780 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11781 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11782 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11783 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11785 /* Setup the depth/stencil surface. */
11786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11787 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11789 hr = IDirect3DDevice9_BeginScene(device);
11790 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11792 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11793 hr = IDirect3DDevice9_EndScene(device);
11794 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11796 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11797 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11799 hr = IDirect3DDevice9_BeginScene(device);
11800 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11802 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11803 hr = IDirect3DDevice9_EndScene(device);
11804 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11806 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11807 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11808 IDirect3DSurface9_Release(ds);
11809 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11810 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11811 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11812 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11814 /* Read the depth values back. */
11815 hr = IDirect3DDevice9_BeginScene(device);
11816 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11818 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11819 hr = IDirect3DDevice9_EndScene(device);
11820 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11822 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11824 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11825 ok(color_match(color, expected_colors[i].color, 1),
11826 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11827 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11831 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11833 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11834 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11835 IDirect3DSurface9_Release(original_ds);
11836 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11837 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11838 IDirect3DTexture9_Release(texture);
11839 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11840 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11841 IDirect3DPixelShader9_Release(ps);
11843 IDirect3DSurface9_Release(original_rt);
11844 IDirect3DSurface9_Release(rt);
11847 static void shadow_test(IDirect3DDevice9 *device)
11849 static const DWORD ps_code[] =
11851 0xffff0200, /* ps_2_0 */
11852 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11853 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11854 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11855 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11856 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11857 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11858 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11859 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11860 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11861 0x0000ffff, /* end */
11863 struct
11865 D3DFORMAT format;
11866 const char *name;
11868 formats[] =
11870 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11871 {D3DFMT_D32, "D3DFMT_D32"},
11872 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11873 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11874 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11875 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11876 {D3DFMT_D16, "D3DFMT_D16"},
11877 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11878 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11880 struct
11882 float x, y, z;
11883 float s, t, p, q;
11885 quad[] =
11887 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11888 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11889 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11890 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11892 struct
11894 UINT x, y;
11895 D3DCOLOR color;
11897 expected_colors[] =
11899 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11900 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11901 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11902 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11903 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11904 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11905 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11906 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11909 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11910 IDirect3DPixelShader9 *ps;
11911 IDirect3D9 *d3d9;
11912 D3DCAPS9 caps;
11913 HRESULT hr;
11914 UINT i;
11916 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11917 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11918 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11920 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11921 return;
11924 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11925 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11926 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11927 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11928 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11929 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11931 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11932 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11933 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11934 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11935 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11937 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11938 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11940 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11942 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11944 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11946 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11948 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11949 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11950 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11951 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11952 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11953 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11954 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11955 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11956 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11957 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11959 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11961 D3DFORMAT format = formats[i].format;
11962 IDirect3DTexture9 *texture;
11963 IDirect3DSurface9 *ds;
11964 unsigned int j;
11966 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11967 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11968 if (FAILED(hr)) continue;
11970 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11971 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11972 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11974 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11975 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11977 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11978 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11980 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11981 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11983 IDirect3DDevice9_SetPixelShader(device, NULL);
11984 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11986 /* Setup the depth/stencil surface. */
11987 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11988 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11990 hr = IDirect3DDevice9_BeginScene(device);
11991 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11994 hr = IDirect3DDevice9_EndScene(device);
11995 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11997 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11998 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11999 IDirect3DSurface9_Release(ds);
12001 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12002 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12004 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12005 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12007 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12008 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12010 /* Do the actual shadow mapping. */
12011 hr = IDirect3DDevice9_BeginScene(device);
12012 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12013 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12014 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12015 hr = IDirect3DDevice9_EndScene(device);
12016 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12018 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12019 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12020 IDirect3DTexture9_Release(texture);
12022 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12024 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12025 ok(color_match(color, expected_colors[j].color, 0),
12026 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12027 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12028 formats[i].name, color);
12031 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12032 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12035 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12036 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12037 IDirect3DPixelShader9_Release(ps);
12039 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12040 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12041 IDirect3DSurface9_Release(original_ds);
12043 IDirect3DSurface9_Release(original_rt);
12044 IDirect3DSurface9_Release(rt);
12046 IDirect3D9_Release(d3d9);
12049 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12051 const struct vertex quad1[] =
12053 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12054 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12055 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
12056 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
12058 const struct vertex quad2[] =
12060 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12061 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12062 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
12063 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
12065 D3DCOLOR color;
12066 HRESULT hr;
12068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12069 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12071 hr = IDirect3DDevice9_BeginScene(device);
12072 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12074 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12075 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12078 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12080 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12083 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12085 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12087 hr = IDirect3DDevice9_EndScene(device);
12088 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12090 color = getPixelColor(device, 1, 240);
12091 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12092 color = getPixelColor(device, 638, 240);
12093 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12095 color = getPixelColor(device, 1, 241);
12096 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12097 color = getPixelColor(device, 638, 241);
12098 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12101 static void clip_planes_test(IDirect3DDevice9 *device)
12103 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12105 const DWORD shader_code[] = {
12106 0xfffe0200, /* vs_2_0 */
12107 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12108 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12109 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12110 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12111 0x0000ffff /* end */
12113 IDirect3DVertexShader9 *shader;
12115 IDirect3DTexture9 *offscreen = NULL;
12116 IDirect3DSurface9 *offscreen_surface, *original_rt;
12117 HRESULT hr;
12119 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12120 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12123 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12125 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12127 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12129 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12131 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12132 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12133 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12134 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12136 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12138 clip_planes(device, "Onscreen FFP");
12140 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12141 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12142 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12143 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12144 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12147 clip_planes(device, "Offscreen FFP");
12149 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12150 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12152 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12153 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12154 IDirect3DDevice9_SetVertexShader(device, shader);
12155 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12157 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12158 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12160 clip_planes(device, "Onscreen vertex shader");
12162 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12163 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12165 clip_planes(device, "Offscreen vertex shader");
12167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12168 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12170 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12171 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12172 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12173 IDirect3DVertexShader9_Release(shader);
12174 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12175 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12176 IDirect3DSurface9_Release(original_rt);
12177 IDirect3DSurface9_Release(offscreen_surface);
12178 IDirect3DTexture9_Release(offscreen);
12181 static void fp_special_test(IDirect3DDevice9 *device)
12183 static const DWORD vs_header[] =
12185 0xfffe0200, /* vs_2_0 */
12186 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12187 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12188 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
12191 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
12192 static const DWORD vs_pow[] =
12193 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
12194 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
12195 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
12196 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
12197 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
12198 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
12199 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
12200 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
12202 static const DWORD vs_footer[] =
12204 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
12205 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
12206 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
12207 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
12208 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12209 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
12210 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
12211 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
12212 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12213 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
12214 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
12215 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
12216 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
12217 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
12218 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12219 0x0000ffff, /* end */
12222 static const struct
12224 const char *name;
12225 const DWORD *ops;
12226 DWORD size;
12227 D3DCOLOR r600;
12228 D3DCOLOR nv40;
12229 D3DCOLOR nv50;
12231 vs_body[] =
12233 /* The basic ideas here are:
12234 * 2.0 * +/-INF == +/-INF
12235 * NAN != NAN
12237 * The vertex shader value is written to the red component, with 0.0
12238 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12239 * result in 0x00. The pixel shader value is written to the green
12240 * component, but here 0.0 also results in 0x00. The actual value is
12241 * written to the blue component.
12243 * There are considerable differences between graphics cards in how
12244 * these are handled, but pow and nrm never generate INF or NAN. */
12245 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
12246 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
12247 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
12248 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12249 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
12250 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12251 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12252 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000},
12255 static const DWORD ps_code[] =
12257 0xffff0200, /* ps_2_0 */
12258 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12259 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
12260 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
12261 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
12262 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
12263 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
12264 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
12265 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
12266 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
12267 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
12268 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
12269 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
12270 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
12271 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
12272 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
12273 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
12274 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
12275 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
12276 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
12277 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
12278 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
12279 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12280 0x0000ffff, /* end */
12283 struct
12285 float x, y, z;
12286 float s;
12288 quad[] =
12290 { -1.0f, 1.0f, 0.0f, 0.0f},
12291 { 1.0f, 1.0f, 1.0f, 0.0f},
12292 { -1.0f, -1.0f, 0.0f, 0.0f},
12293 { 1.0f, -1.0f, 1.0f, 0.0f},
12296 IDirect3DPixelShader9 *ps;
12297 UINT body_size = 0;
12298 DWORD *vs_code;
12299 D3DCAPS9 caps;
12300 HRESULT hr;
12301 UINT i;
12303 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12304 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12305 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12307 skip("No shader model 2.0 support, skipping floating point specials test.\n");
12308 return;
12311 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12312 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12314 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12315 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12316 IDirect3DDevice9_SetPixelShader(device, ps);
12317 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12320 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12322 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12323 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12325 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12327 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12330 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12331 memcpy(vs_code, vs_header, sizeof(vs_header));
12333 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12335 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12336 IDirect3DVertexShader9 *vs;
12337 D3DCOLOR color;
12339 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12340 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12341 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12343 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12344 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12345 IDirect3DDevice9_SetVertexShader(device, vs);
12346 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12348 hr = IDirect3DDevice9_BeginScene(device);
12349 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12352 hr = IDirect3DDevice9_EndScene(device);
12353 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12355 color = getPixelColor(device, 320, 240);
12356 ok(color_match(color, vs_body[i].r600, 1)
12357 || color_match(color, vs_body[i].nv40, 1)
12358 || color_match(color, vs_body[i].nv50, 1),
12359 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12360 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12362 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12363 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12365 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12366 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12367 IDirect3DVertexShader9_Release(vs);
12370 HeapFree(GetProcessHeap(), 0, vs_code);
12372 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12373 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12374 IDirect3DPixelShader9_Release(ps);
12377 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12379 IDirect3D9 *d3d;
12380 IDirect3DSurface9 *rt, *backbuffer;
12381 IDirect3DTexture9 *texture;
12382 HRESULT hr;
12383 int i;
12384 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12385 static const struct
12387 D3DFORMAT fmt;
12388 const char *name;
12390 formats[] =
12392 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12393 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12394 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12395 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12396 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12398 static const struct
12400 float x, y, z;
12401 float u, v;
12403 quad[] =
12405 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12406 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12407 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12408 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12411 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12412 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12413 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12414 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12415 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12416 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12417 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12418 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12420 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12422 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12424 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12425 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12427 skip("Format %s not supported as render target, skipping test.\n",
12428 formats[i].name);
12429 continue;
12432 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12433 D3DPOOL_DEFAULT, &texture, NULL);
12434 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12436 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12438 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12439 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12440 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12441 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12442 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12443 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12445 hr = IDirect3DDevice9_BeginScene(device);
12446 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12447 if(SUCCEEDED(hr))
12449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12450 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12451 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12452 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12454 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12457 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12458 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12459 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12460 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12461 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12462 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12463 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12465 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12466 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12467 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12469 hr = IDirect3DDevice9_EndScene(device);
12470 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12473 IDirect3DSurface9_Release(rt);
12474 IDirect3DTexture9_Release(texture);
12476 color = getPixelColor(device, 360, 240);
12477 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12478 D3DUSAGE_QUERY_SRGBWRITE,
12479 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12481 /* Big slop for R5G6B5 */
12482 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12483 formats[i].name, color_srgb, color);
12485 else
12487 /* Big slop for R5G6B5 */
12488 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12489 formats[i].name, color_rgb, color);
12492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12493 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12496 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12497 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12499 IDirect3D9_Release(d3d);
12500 IDirect3DSurface9_Release(backbuffer);
12503 static void ds_size_test(IDirect3DDevice9 *device)
12505 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12506 HRESULT hr;
12507 DWORD num_passes;
12508 struct
12510 float x, y, z;
12512 quad[] =
12514 {-1.0, -1.0, 0.0 },
12515 {-1.0, 1.0, 0.0 },
12516 { 1.0, -1.0, 0.0 },
12517 { 1.0, 1.0, 0.0 }
12520 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12521 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12522 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12523 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12524 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12525 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12528 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12530 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12532 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12533 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12534 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12535 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12536 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12537 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12538 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12539 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12540 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12541 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12542 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12543 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12544 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12546 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12547 * but does not change the surface's contents. */
12548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12549 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12550 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12551 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12552 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12553 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12555 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12557 /* Turning on any depth-related state results in a ValidateDevice failure */
12558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12559 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12560 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12561 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12562 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12564 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12566 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12567 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12568 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12569 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12571 /* Try to draw with the device in an invalid state */
12572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12573 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12574 hr = IDirect3DDevice9_BeginScene(device);
12575 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12576 if(SUCCEEDED(hr))
12578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12579 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12580 hr = IDirect3DDevice9_EndScene(device);
12581 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12583 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12584 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12585 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12588 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12589 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12590 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12591 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12592 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12593 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12595 IDirect3DSurface9_Release(readback);
12596 IDirect3DSurface9_Release(ds);
12597 IDirect3DSurface9_Release(rt);
12598 IDirect3DSurface9_Release(old_rt);
12599 IDirect3DSurface9_Release(old_ds);
12602 static void unbound_sampler_test(IDirect3DDevice9 *device)
12604 HRESULT hr;
12605 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12606 IDirect3DSurface9 *rt, *old_rt;
12607 DWORD color;
12609 static const DWORD ps_code[] =
12611 0xffff0200, /* ps_2_0 */
12612 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12613 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12614 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12615 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12616 0x0000ffff, /* end */
12618 static const DWORD ps_code_cube[] =
12620 0xffff0200, /* ps_2_0 */
12621 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
12622 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12623 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12624 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12625 0x0000ffff, /* end */
12627 static const DWORD ps_code_volume[] =
12629 0xffff0200, /* ps_2_0 */
12630 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
12631 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12632 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12633 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12634 0x0000ffff, /* end */
12637 static const struct
12639 float x, y, z;
12640 float u, v;
12642 quad[] =
12644 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12645 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12646 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12647 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12650 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12651 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12653 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12654 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12655 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12656 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12657 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12658 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12660 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12661 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12663 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12664 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12666 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12667 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12669 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12670 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12672 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12673 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12675 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12676 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12678 hr = IDirect3DDevice9_BeginScene(device);
12679 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12680 if(SUCCEEDED(hr))
12682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12683 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12685 hr = IDirect3DDevice9_EndScene(device);
12686 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12689 color = getPixelColorFromSurface(rt, 32, 32);
12690 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12692 /* Now try with a cube texture */
12693 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12694 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12696 hr = IDirect3DDevice9_BeginScene(device);
12697 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12698 if (SUCCEEDED(hr))
12700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12701 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12703 hr = IDirect3DDevice9_EndScene(device);
12704 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12707 color = getPixelColorFromSurface(rt, 32, 32);
12708 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12710 /* And then with a volume texture */
12711 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12712 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12714 hr = IDirect3DDevice9_BeginScene(device);
12715 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12716 if (SUCCEEDED(hr))
12718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12719 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12721 hr = IDirect3DDevice9_EndScene(device);
12722 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12725 color = getPixelColorFromSurface(rt, 32, 32);
12726 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12728 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12729 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12731 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12732 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12734 IDirect3DSurface9_Release(rt);
12735 IDirect3DSurface9_Release(old_rt);
12736 IDirect3DPixelShader9_Release(ps);
12737 IDirect3DPixelShader9_Release(ps_cube);
12738 IDirect3DPixelShader9_Release(ps_volume);
12741 static void update_surface_test(IDirect3DDevice9 *device)
12743 static const BYTE blocks[][8] =
12745 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12746 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12747 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12748 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12749 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12750 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12751 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12753 static const struct
12755 UINT x, y;
12756 D3DCOLOR color;
12758 expected_colors[] =
12760 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12761 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12762 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12763 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12764 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12765 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12766 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12768 static const struct
12770 float x, y, z, w;
12771 float u, v;
12773 tri[] =
12775 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12776 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12777 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12779 static const RECT rect_2x2 = {0, 0, 2, 2};
12780 static const struct
12782 UINT src_level;
12783 UINT dst_level;
12784 const RECT *r;
12785 HRESULT hr;
12787 block_size_tests[] =
12789 {1, 0, NULL, D3D_OK},
12790 {0, 1, NULL, D3DERR_INVALIDCALL},
12791 {5, 4, NULL, D3DERR_INVALIDCALL},
12792 {4, 5, NULL, D3DERR_INVALIDCALL},
12793 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12794 {5, 5, &rect_2x2, D3D_OK},
12797 IDirect3DSurface9 *src_surface, *dst_surface;
12798 IDirect3DTexture9 *src_tex, *dst_tex;
12799 IDirect3D9 *d3d;
12800 UINT count, i;
12801 HRESULT hr;
12803 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12804 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12806 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12807 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12808 IDirect3D9_Release(d3d);
12809 if (FAILED(hr))
12811 skip("DXT1 not supported, skipping test.\n");
12812 return;
12815 IDirect3D9_Release(d3d);
12817 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12818 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12819 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12820 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12822 count = IDirect3DTexture9_GetLevelCount(src_tex);
12823 ok(count == 7, "Got level count %u, expected 7.\n", count);
12825 for (i = 0; i < count; ++i)
12827 UINT row_count, block_count, x, y;
12828 D3DSURFACE_DESC desc;
12829 BYTE *row, *block;
12830 D3DLOCKED_RECT r;
12832 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12833 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12835 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12836 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12838 row_count = ((desc.Height + 3) & ~3) / 4;
12839 block_count = ((desc.Width + 3) & ~3) / 4;
12840 row = r.pBits;
12842 for (y = 0; y < row_count; ++y)
12844 block = row;
12845 for (x = 0; x < block_count; ++x)
12847 memcpy(block, blocks[i], sizeof(blocks[i]));
12848 block += sizeof(blocks[i]);
12850 row += r.Pitch;
12853 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12854 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12857 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12859 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12860 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12861 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12862 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12864 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12865 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12866 hr, i, block_size_tests[i].hr);
12868 IDirect3DSurface9_Release(dst_surface);
12869 IDirect3DSurface9_Release(src_surface);
12872 for (i = 0; i < count; ++i)
12874 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12875 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12876 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12877 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12879 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12880 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12882 IDirect3DSurface9_Release(dst_surface);
12883 IDirect3DSurface9_Release(src_surface);
12886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12887 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12888 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12889 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12890 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12891 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12892 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12893 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12894 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12895 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12896 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12897 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12899 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12900 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12902 hr = IDirect3DDevice9_BeginScene(device);
12903 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12905 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12906 hr = IDirect3DDevice9_EndScene(device);
12907 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12909 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12911 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12912 ok(color_match(color, expected_colors[i].color, 0),
12913 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12914 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12917 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12918 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12920 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12921 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12922 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12923 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12924 IDirect3DTexture9_Release(dst_tex);
12925 IDirect3DTexture9_Release(src_tex);
12928 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
12930 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
12931 IDirect3D9 *d3d9;
12932 HRESULT hr;
12934 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12935 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
12936 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
12937 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
12938 IDirect3D9_Release(d3d9);
12939 if (FAILED(hr))
12941 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
12942 return;
12945 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
12946 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
12947 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
12948 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
12949 D3DPOOL_SYSTEMMEM, &readback, NULL);
12950 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
12952 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12953 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12954 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12955 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
12957 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12958 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
12959 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12960 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
12963 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
12964 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12965 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
12967 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12968 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12969 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12970 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
12972 IDirect3DSurface9_Release(original_ds);
12973 IDirect3DSurface9_Release(original_rt);
12974 IDirect3DSurface9_Release(readback);
12975 IDirect3DSurface9_Release(rt);
12978 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
12980 IDirect3DDevice9 *device = 0;
12981 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
12982 D3DCAPS9 caps;
12983 HRESULT hr;
12984 D3DPRESENT_PARAMETERS present_parameters;
12985 unsigned int i;
12986 static const struct
12988 float x, y, z;
12989 D3DCOLOR color;
12991 quad_1[] =
12993 { -1.0f, 1.0f, 0.0f, 0xffff0000},
12994 { 1.0f, 1.0f, 1.0f, 0xffff0000},
12995 { -1.0f, -1.0f, 0.0f, 0xffff0000},
12996 { 1.0f, -1.0f, 1.0f, 0xffff0000},
12998 quad_2[] =
13000 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
13001 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
13002 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13003 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
13005 static const struct
13007 UINT x, y;
13008 D3DCOLOR color;
13010 expected_colors[] =
13012 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13013 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13014 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13015 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13016 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13017 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13018 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13019 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13022 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13023 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13024 if (FAILED(hr))
13026 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13027 return;
13029 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13030 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13031 if (FAILED(hr))
13033 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13034 return;
13037 ZeroMemory(&present_parameters, sizeof(present_parameters));
13038 present_parameters.Windowed = TRUE;
13039 present_parameters.hDeviceWindow = create_window();
13040 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13041 present_parameters.BackBufferWidth = 640;
13042 present_parameters.BackBufferHeight = 480;
13043 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13044 present_parameters.EnableAutoDepthStencil = TRUE;
13045 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13046 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13048 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13049 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13050 &present_parameters, &device);
13051 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13053 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13054 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13055 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13057 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13058 goto cleanup;
13061 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13062 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13063 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13064 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13065 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13066 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13068 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13069 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13070 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13071 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13074 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13076 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13078 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13080 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13082 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13084 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13085 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13087 /* Render onscreen and then offscreen */
13088 hr = IDirect3DDevice9_BeginScene(device);
13089 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13091 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13092 hr = IDirect3DDevice9_EndScene(device);
13093 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13095 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13096 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13097 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13098 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13100 hr = IDirect3DDevice9_BeginScene(device);
13101 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13104 hr = IDirect3DDevice9_EndScene(device);
13105 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13107 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13108 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13110 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13112 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13113 ok(color_match(color, expected_colors[i].color, 1),
13114 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13115 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13118 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13119 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13120 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13121 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13123 /* Render offscreen and then onscreen */
13124 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13125 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13126 IDirect3DSurface9_Release(ds);
13127 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13128 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13129 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13130 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13133 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13135 hr = IDirect3DDevice9_BeginScene(device);
13136 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13138 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13139 hr = IDirect3DDevice9_EndScene(device);
13140 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13142 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13143 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13144 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13145 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13147 hr = IDirect3DDevice9_BeginScene(device);
13148 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13150 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13151 hr = IDirect3DDevice9_EndScene(device);
13152 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13154 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13155 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13157 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13159 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13160 ok(color_match(color, expected_colors[i].color, 1),
13161 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13162 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13165 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13166 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13168 IDirect3DSurface9_Release(ds);
13169 IDirect3DSurface9_Release(readback);
13170 IDirect3DSurface9_Release(rt);
13171 IDirect3DSurface9_Release(original_rt);
13172 cleanup_device(device);
13174 ZeroMemory(&present_parameters, sizeof(present_parameters));
13175 present_parameters.Windowed = TRUE;
13176 present_parameters.hDeviceWindow = create_window();
13177 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13178 present_parameters.BackBufferWidth = 640;
13179 present_parameters.BackBufferHeight = 480;
13180 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13181 present_parameters.EnableAutoDepthStencil = TRUE;
13182 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13183 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13185 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13186 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13187 &present_parameters, &device);
13188 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13191 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13194 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13195 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13196 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13197 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13198 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13199 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13200 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13201 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13203 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13204 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13205 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13206 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13207 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13208 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13209 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13210 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13213 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13215 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13217 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13219 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13220 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13221 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13223 /* Render to a multisampled offscreen frame buffer and then blit to
13224 * the onscreen (not multisampled) frame buffer. */
13225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13226 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13228 hr = IDirect3DDevice9_BeginScene(device);
13229 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13231 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13232 hr = IDirect3DDevice9_EndScene(device);
13233 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13235 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13236 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13237 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13238 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13240 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13241 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13242 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13243 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13245 hr = IDirect3DDevice9_BeginScene(device);
13246 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13248 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13249 hr = IDirect3DDevice9_EndScene(device);
13250 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13252 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13253 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13255 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13257 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13258 if (i % 4 < 2)
13259 todo_wine ok(color_match(color, expected_colors[i].color, 1),
13260 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13261 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13262 else
13263 ok(color_match(color, expected_colors[i].color, 1),
13264 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13265 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13268 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13269 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13271 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13272 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13273 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13274 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13276 IDirect3DSurface9_Release(original_ds);
13277 IDirect3DSurface9_Release(original_rt);
13278 IDirect3DSurface9_Release(ds);
13279 IDirect3DSurface9_Release(readback);
13280 IDirect3DSurface9_Release(rt);
13281 cleanup:
13282 cleanup_device(device);
13285 START_TEST(visual)
13287 IDirect3D9 *d3d9;
13288 IDirect3DDevice9 *device_ptr;
13289 D3DCAPS9 caps;
13290 HRESULT hr;
13291 DWORD color;
13293 d3d9_handle = LoadLibraryA("d3d9.dll");
13294 if (!d3d9_handle)
13296 skip("Could not load d3d9.dll\n");
13297 return;
13300 device_ptr = init_d3d9();
13301 if (!device_ptr)
13303 skip("Creating the device failed\n");
13304 return;
13307 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
13309 /* Check for the reliability of the returned data */
13310 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
13311 if(FAILED(hr))
13313 skip("Clear failed, can't assure correctness of the test results, skipping\n");
13314 goto cleanup;
13317 color = getPixelColor(device_ptr, 1, 1);
13318 if(color !=0x00ff0000)
13320 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
13321 goto cleanup;
13323 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
13325 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
13326 if(FAILED(hr))
13328 skip("Clear failed, can't assure correctness of the test results, skipping\n");
13329 goto cleanup;
13332 color = getPixelColor(device_ptr, 639, 479);
13333 if(color != 0x0000ddee)
13335 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
13336 goto cleanup;
13338 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
13340 /* Now execute the real tests */
13341 depth_clamp_test(device_ptr);
13342 stretchrect_test(device_ptr);
13343 lighting_test(device_ptr);
13344 clear_test(device_ptr);
13345 color_fill_test(device_ptr);
13346 fog_test(device_ptr);
13347 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
13349 test_cube_wrap(device_ptr);
13350 } else {
13351 skip("No cube texture support\n");
13353 z_range_test(device_ptr);
13354 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
13356 maxmip_test(device_ptr);
13358 else
13360 skip("No mipmap support\n");
13362 offscreen_test(device_ptr);
13363 ds_size_test(device_ptr);
13364 alpha_test(device_ptr);
13365 shademode_test(device_ptr);
13366 srgbtexture_test(device_ptr);
13367 release_buffer_test(device_ptr);
13368 float_texture_test(device_ptr);
13369 g16r16_texture_test(device_ptr);
13370 pixelshader_blending_test(device_ptr);
13371 texture_transform_flags_test(device_ptr);
13372 autogen_mipmap_test(device_ptr);
13373 fixed_function_decl_test(device_ptr);
13374 conditional_np2_repeat_test(device_ptr);
13375 fixed_function_bumpmap_test(device_ptr);
13376 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
13377 stencil_cull_test(device_ptr);
13378 } else {
13379 skip("No two sided stencil support\n");
13381 pointsize_test(device_ptr);
13382 tssargtemp_test(device_ptr);
13383 np2_stretch_rect_test(device_ptr);
13384 yuv_color_test(device_ptr);
13385 zwriteenable_test(device_ptr);
13386 alphatest_test(device_ptr);
13387 viewport_test(device_ptr);
13389 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13391 test_constant_clamp_vs(device_ptr);
13392 test_compare_instructions(device_ptr);
13394 else skip("No vs_1_1 support\n");
13396 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
13398 test_mova(device_ptr);
13399 loop_index_test(device_ptr);
13400 sincos_test(device_ptr);
13401 sgn_test(device_ptr);
13402 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
13403 test_vshader_input(device_ptr);
13404 test_vshader_float16(device_ptr);
13405 stream_test(device_ptr);
13406 } else {
13407 skip("No vs_3_0 support\n");
13410 else skip("No vs_2_0 support\n");
13412 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
13414 fog_with_shader_test(device_ptr);
13416 else skip("No vs_1_1 and ps_1_1 support\n");
13418 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
13420 texbem_test(device_ptr);
13421 texdepth_test(device_ptr);
13422 texkill_test(device_ptr);
13423 x8l8v8u8_test(device_ptr);
13424 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
13425 constant_clamp_ps_test(device_ptr);
13426 cnd_test(device_ptr);
13427 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
13428 dp2add_ps_test(device_ptr);
13429 unbound_sampler_test(device_ptr);
13430 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
13431 nested_loop_test(device_ptr);
13432 pretransformed_varying_test(device_ptr);
13433 vFace_register_test(device_ptr);
13434 vpos_register_test(device_ptr);
13435 multiple_rendertargets_test(device_ptr);
13436 } else {
13437 skip("No ps_3_0 or vs_3_0 support\n");
13439 } else {
13440 skip("No ps_2_0 support\n");
13444 else skip("No ps_1_1 support\n");
13446 texop_test(device_ptr);
13447 texop_range_test(device_ptr);
13448 alphareplicate_test(device_ptr);
13449 dp3_alpha_test(device_ptr);
13450 depth_buffer_test(device_ptr);
13451 depth_buffer2_test(device_ptr);
13452 depth_blit_test(device_ptr);
13453 intz_test(device_ptr);
13454 shadow_test(device_ptr);
13455 fp_special_test(device_ptr);
13456 depth_bounds_test(device_ptr);
13457 srgbwrite_format_test(device_ptr);
13458 clip_planes_test(device_ptr);
13459 update_surface_test(device_ptr);
13460 multisample_get_rtdata_test(device_ptr);
13462 hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
13463 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13464 cleanup_device(device_ptr);
13465 device_ptr = NULL;
13467 multisampled_depth_buffer_test(d3d9);
13468 IDirect3D9_Release(d3d9);
13470 cleanup:
13471 cleanup_device(device_ptr);