jscript: Don't set constructor property to each object instance, it belongs to their...
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blobbe2d7dcf810707ea5c2080c4848e49ca66d67617
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 struct vec3
39 float x, y, z;
42 struct vec4
44 float x, y, z, w;
47 static HWND create_window(void)
49 WNDCLASS wc = {0};
50 HWND ret;
51 wc.lpfnWndProc = DefWindowProc;
52 wc.lpszClassName = "d3d9_test_wc";
53 RegisterClass(&wc);
55 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
56 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
57 ShowWindow(ret, SW_SHOW);
58 return ret;
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
63 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64 c1 >>= 8; c2 >>= 8;
65 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66 c1 >>= 8; c2 >>= 8;
67 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68 c1 >>= 8; c2 >>= 8;
69 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
70 return TRUE;
73 /* Locks a given surface and returns the color at (x,y). It's the caller's
74 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
75 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
77 DWORD color;
78 HRESULT hr;
79 D3DSURFACE_DESC desc;
80 RECT rectToLock = {x, y, x+1, y+1};
81 D3DLOCKED_RECT lockedRect;
83 hr = IDirect3DSurface9_GetDesc(surface, &desc);
84 if(FAILED(hr)) /* This is not a test */
86 trace("Can't get the surface description, hr=%08x\n", hr);
87 return 0xdeadbeef;
90 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
91 if(FAILED(hr)) /* This is not a test */
93 trace("Can't lock the surface, hr=%08x\n", hr);
94 return 0xdeadbeef;
96 switch(desc.Format) {
97 case D3DFMT_A8R8G8B8:
99 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
100 break;
102 default:
103 trace("Error: unknown surface format: %d\n", desc.Format);
104 color = 0xdeadbeef;
105 break;
107 hr = IDirect3DSurface9_UnlockRect(surface);
108 if(FAILED(hr))
110 trace("Can't unlock the surface, hr=%08x\n", hr);
112 return color;
115 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
117 DWORD ret;
118 IDirect3DSurface9 *surf = NULL, *target = NULL;
119 HRESULT hr;
120 D3DLOCKED_RECT lockedRect;
121 RECT rectToLock = {x, y, x+1, y+1};
123 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
124 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
125 if (FAILED(hr) || !surf)
127 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
128 return 0xdeadbeef;
131 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
132 if(FAILED(hr))
134 trace("Can't get the render target, hr=%08x\n", hr);
135 ret = 0xdeadbeed;
136 goto out;
139 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
140 if (FAILED(hr))
142 trace("Can't read the render target data, hr=%08x\n", hr);
143 ret = 0xdeadbeec;
144 goto out;
147 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
148 if(FAILED(hr))
150 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
151 ret = 0xdeadbeeb;
152 goto out;
155 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
156 * really important for these tests
158 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
159 hr = IDirect3DSurface9_UnlockRect(surf);
160 if(FAILED(hr))
162 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
165 out:
166 if(target) IDirect3DSurface9_Release(target);
167 if(surf) IDirect3DSurface9_Release(surf);
168 return ret;
171 static IDirect3DDevice9 *init_d3d9(void)
173 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
174 IDirect3D9 *d3d9_ptr = 0;
175 IDirect3DDevice9 *device_ptr = 0;
176 D3DPRESENT_PARAMETERS present_parameters;
177 HRESULT hr;
178 D3DADAPTER_IDENTIFIER9 identifier;
180 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
181 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
182 if (!d3d9_create) return NULL;
184 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
185 if (!d3d9_ptr)
187 win_skip("could not create D3D9\n");
188 return NULL;
191 ZeroMemory(&present_parameters, sizeof(present_parameters));
192 present_parameters.Windowed = TRUE;
193 present_parameters.hDeviceWindow = create_window();
194 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
195 present_parameters.BackBufferWidth = 640;
196 present_parameters.BackBufferHeight = 480;
197 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
198 present_parameters.EnableAutoDepthStencil = TRUE;
199 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
201 memset(&identifier, 0, sizeof(identifier));
202 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
203 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
204 trace("Driver string: \"%s\"\n", identifier.Driver);
205 trace("Description string: \"%s\"\n", identifier.Description);
206 ok(identifier.Description[0] != '\0', "Empty driver description\n");
207 trace("Device name string: \"%s\"\n", identifier.DeviceName);
208 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
209 trace("Driver version %d.%d.%d.%d\n",
210 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
211 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
213 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
214 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
215 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
216 "Failed to create a device, hr %#x.\n", hr);
218 return device_ptr;
221 static void cleanup_device(IDirect3DDevice9 *device)
223 if (device)
225 D3DPRESENT_PARAMETERS present_parameters;
226 IDirect3DSwapChain9 *swapchain;
227 ULONG ref;
229 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
230 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
231 IDirect3DSwapChain9_Release(swapchain);
232 ref = IDirect3DDevice9_Release(device);
233 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
234 DestroyWindow(present_parameters.hDeviceWindow);
238 struct vertex
240 float x, y, z;
241 DWORD diffuse;
244 struct tvertex
246 float x, y, z, rhw;
247 DWORD diffuse;
250 struct nvertex
252 float x, y, z;
253 float nx, ny, nz;
254 DWORD diffuse;
257 static void lighting_test(IDirect3DDevice9 *device)
259 HRESULT hr;
260 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
261 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
262 DWORD color;
263 D3DMATERIAL9 material, old_material;
264 DWORD cop, carg;
265 DWORD old_colorwrite;
267 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
268 0.0f, 1.0f, 0.0f, 0.0f,
269 0.0f, 0.0f, 1.0f, 0.0f,
270 0.0f, 0.0f, 0.0f, 1.0f };
272 struct vertex unlitquad[] =
274 {-1.0f, -1.0f, 0.1f, 0xffff0000},
275 {-1.0f, 0.0f, 0.1f, 0xffff0000},
276 { 0.0f, 0.0f, 0.1f, 0xffff0000},
277 { 0.0f, -1.0f, 0.1f, 0xffff0000},
279 struct vertex litquad[] =
281 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
282 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
283 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
284 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
286 struct nvertex unlitnquad[] =
288 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
289 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
290 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
291 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
293 struct nvertex litnquad[] =
295 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
296 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
297 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
298 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
300 WORD Indices[] = {0, 1, 2, 2, 3, 0};
302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
305 /* Setup some states that may cause issues */
306 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
308 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
310 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
311 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
313 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
315 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
327 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
328 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
329 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
333 hr = IDirect3DDevice9_SetFVF(device, 0);
334 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
336 hr = IDirect3DDevice9_SetFVF(device, fvf);
337 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
339 hr = IDirect3DDevice9_BeginScene(device);
340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
341 if(hr == D3D_OK)
343 /* No lights are defined... That means, lit vertices should be entirely black */
344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
345 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
346 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
347 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
348 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
352 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
353 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
354 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
356 hr = IDirect3DDevice9_SetFVF(device, nfvf);
357 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
360 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
361 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
362 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
363 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
366 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
368 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
369 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
371 hr = IDirect3DDevice9_EndScene(device);
372 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
375 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
376 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
377 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
378 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
379 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
380 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
381 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
382 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
384 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
386 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
387 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
388 memset(&material, 0, sizeof(material));
389 material.Diffuse.r = 0.0;
390 material.Diffuse.g = 0.0;
391 material.Diffuse.b = 0.0;
392 material.Diffuse.a = 1.0;
393 material.Ambient.r = 0.0;
394 material.Ambient.g = 0.0;
395 material.Ambient.b = 0.0;
396 material.Ambient.a = 0.0;
397 material.Specular.r = 0.0;
398 material.Specular.g = 0.0;
399 material.Specular.b = 0.0;
400 material.Specular.a = 0.0;
401 material.Emissive.r = 0.0;
402 material.Emissive.g = 0.0;
403 material.Emissive.b = 0.0;
404 material.Emissive.a = 0.0;
405 material.Power = 0.0;
406 hr = IDirect3DDevice9_SetMaterial(device, &material);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
414 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
415 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
416 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
417 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
418 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
421 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
423 hr = IDirect3DDevice9_BeginScene(device);
424 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
425 if(SUCCEEDED(hr)) {
426 struct vertex lighting_test[] = {
427 {-1.0, -1.0, 0.1, 0x8000ff00},
428 { 1.0, -1.0, 0.1, 0x80000000},
429 {-1.0, 1.0, 0.1, 0x8000ff00},
430 { 1.0, 1.0, 0.1, 0x80000000}
432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
435 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
437 hr = IDirect3DDevice9_EndScene(device);
438 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
441 color = getPixelColor(device, 320, 240);
442 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
443 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
445 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
446 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
450 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
454 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
455 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
456 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
457 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
458 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
461 static void clear_test(IDirect3DDevice9 *device)
463 /* Tests the correctness of clearing parameters */
464 HRESULT hr;
465 D3DRECT rect[2];
466 D3DRECT rect_negneg;
467 DWORD color;
468 D3DVIEWPORT9 old_vp, vp;
469 RECT scissor;
470 DWORD oldColorWrite;
471 BOOL invalid_clear_failed = FALSE;
473 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
474 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
476 /* Positive x, negative y */
477 rect[0].x1 = 0;
478 rect[0].y1 = 480;
479 rect[0].x2 = 320;
480 rect[0].y2 = 240;
482 /* Positive x, positive y */
483 rect[1].x1 = 0;
484 rect[1].y1 = 0;
485 rect[1].x2 = 320;
486 rect[1].y2 = 240;
487 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
488 * returns D3D_OK, but ignores the rectangle silently
490 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
491 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
492 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
494 /* negative x, negative y */
495 rect_negneg.x1 = 640;
496 rect_negneg.y1 = 240;
497 rect_negneg.x2 = 320;
498 rect_negneg.y2 = 0;
499 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
500 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
503 color = getPixelColor(device, 160, 360); /* lower left quad */
504 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
505 color = getPixelColor(device, 160, 120); /* upper left quad */
506 if(invalid_clear_failed) {
507 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
508 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
509 } else {
510 /* If the negative rectangle was dropped silently, the correct ones are cleared */
511 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
513 color = getPixelColor(device, 480, 360); /* lower right quad */
514 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
515 color = getPixelColor(device, 480, 120); /* upper right quad */
516 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
518 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
520 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
521 * clear the red quad in the top left part of the render target. For some reason it
522 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
523 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
524 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
525 * pick some obvious value
527 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
528 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
530 /* Test how the viewport affects clears */
531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
532 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
533 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
534 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
536 vp.X = 160;
537 vp.Y = 120;
538 vp.Width = 160;
539 vp.Height = 120;
540 vp.MinZ = 0.0;
541 vp.MaxZ = 1.0;
542 hr = IDirect3DDevice9_SetViewport(device, &vp);
543 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
545 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
547 vp.X = 320;
548 vp.Y = 240;
549 vp.Width = 320;
550 vp.Height = 240;
551 vp.MinZ = 0.0;
552 vp.MaxZ = 1.0;
553 hr = IDirect3DDevice9_SetViewport(device, &vp);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555 rect[0].x1 = 160;
556 rect[0].y1 = 120;
557 rect[0].x2 = 480;
558 rect[0].y2 = 360;
559 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
560 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
562 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
563 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
565 color = getPixelColor(device, 158, 118);
566 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
567 color = getPixelColor(device, 162, 118);
568 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
569 color = getPixelColor(device, 158, 122);
570 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
571 color = getPixelColor(device, 162, 122);
572 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
574 color = getPixelColor(device, 318, 238);
575 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
576 color = getPixelColor(device, 322, 238);
577 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
578 color = getPixelColor(device, 318, 242);
579 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
580 color = getPixelColor(device, 322, 242);
581 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
583 color = getPixelColor(device, 478, 358);
584 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
585 color = getPixelColor(device, 482, 358);
586 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
587 color = getPixelColor(device, 478, 362);
588 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
589 color = getPixelColor(device, 482, 362);
590 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
592 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
594 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
595 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
597 scissor.left = 160;
598 scissor.right = 480;
599 scissor.top = 120;
600 scissor.bottom = 360;
601 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
602 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
604 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
607 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
608 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
609 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
612 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
614 color = getPixelColor(device, 158, 118);
615 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
616 color = getPixelColor(device, 162, 118);
617 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
618 color = getPixelColor(device, 158, 122);
619 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
620 color = getPixelColor(device, 162, 122);
621 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
623 color = getPixelColor(device, 158, 358);
624 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
625 color = getPixelColor(device, 162, 358);
626 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
627 color = getPixelColor(device, 158, 358);
628 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
629 color = getPixelColor(device, 162, 362);
630 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
632 color = getPixelColor(device, 478, 118);
633 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
634 color = getPixelColor(device, 478, 122);
635 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
636 color = getPixelColor(device, 482, 122);
637 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
638 color = getPixelColor(device, 482, 358);
639 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
641 color = getPixelColor(device, 478, 358);
642 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
643 color = getPixelColor(device, 478, 362);
644 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
645 color = getPixelColor(device, 482, 358);
646 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
647 color = getPixelColor(device, 482, 362);
648 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
650 color = getPixelColor(device, 318, 238);
651 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
652 color = getPixelColor(device, 318, 242);
653 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
654 color = getPixelColor(device, 322, 238);
655 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
656 color = getPixelColor(device, 322, 242);
657 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
659 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
661 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
662 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
666 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
667 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
668 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
674 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
676 /* Colorwriteenable does not affect the clear */
677 color = getPixelColor(device, 320, 240);
678 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
680 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
683 static void color_fill_test(IDirect3DDevice9 *device)
685 HRESULT hr;
686 IDirect3DSurface9 *backbuffer = NULL;
687 IDirect3DSurface9 *rt_surface = NULL;
688 IDirect3DSurface9 *offscreen_surface = NULL;
689 DWORD fill_color, color;
691 /* Test ColorFill on a the backbuffer (should pass) */
692 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
693 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
694 if(backbuffer)
696 fill_color = 0x112233;
697 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
698 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
700 color = getPixelColor(device, 0, 0);
701 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
703 IDirect3DSurface9_Release(backbuffer);
706 /* Test ColorFill on a render target surface (should pass) */
707 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
708 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
709 if(rt_surface)
711 fill_color = 0x445566;
712 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
713 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
715 color = getPixelColorFromSurface(rt_surface, 0, 0);
716 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
718 IDirect3DSurface9_Release(rt_surface);
721 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
722 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
723 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
724 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
725 if(offscreen_surface)
727 fill_color = 0x778899;
728 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
729 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
731 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
732 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
734 IDirect3DSurface9_Release(offscreen_surface);
737 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
738 offscreen_surface = NULL;
739 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
740 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
741 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
742 if(offscreen_surface)
744 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
745 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
747 IDirect3DSurface9_Release(offscreen_surface);
751 typedef struct {
752 float in[4];
753 DWORD out;
754 } test_data_t;
757 * c7 mova ARGB mov ARGB
758 * -2.4 -2 0x00ffff00 -3 0x00ff0000
759 * -1.6 -2 0x00ffff00 -2 0x00ffff00
760 * -0.4 0 0x0000ffff -1 0x0000ff00
761 * 0.4 0 0x0000ffff 0 0x0000ffff
762 * 1.6 2 0x00ff00ff 1 0x000000ff
763 * 2.4 2 0x00ff00ff 2 0x00ff00ff
765 static void test_mova(IDirect3DDevice9 *device)
767 static const DWORD mova_test[] = {
768 0xfffe0200, /* vs_2_0 */
769 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
770 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
771 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
772 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
773 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
774 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
775 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
776 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
777 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
778 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
779 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
780 0x0000ffff /* END */
782 static const DWORD mov_test[] = {
783 0xfffe0101, /* vs_1_1 */
784 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
785 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
786 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
787 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
788 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
789 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
790 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
791 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
792 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
793 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
794 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
795 0x0000ffff /* END */
798 static const test_data_t test_data[2][6] = {
800 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
801 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
802 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
803 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
804 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
805 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
808 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
809 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
810 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
811 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
812 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
813 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
817 static const float quad[][3] = {
818 {-1.0f, -1.0f, 0.0f},
819 {-1.0f, 1.0f, 0.0f},
820 { 1.0f, -1.0f, 0.0f},
821 { 1.0f, 1.0f, 0.0f},
824 static const D3DVERTEXELEMENT9 decl_elements[] = {
825 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
826 D3DDECL_END()
829 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
830 IDirect3DVertexShader9 *mova_shader = NULL;
831 IDirect3DVertexShader9 *mov_shader = NULL;
832 HRESULT hr;
833 UINT i, j;
835 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
836 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
837 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
838 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
839 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
840 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
841 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
842 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
844 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
845 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
846 for(j = 0; j < 2; ++j)
848 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
850 DWORD color;
852 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
853 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
855 hr = IDirect3DDevice9_BeginScene(device);
856 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
858 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
859 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
861 hr = IDirect3DDevice9_EndScene(device);
862 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
864 color = getPixelColor(device, 320, 240);
865 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
866 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
868 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
869 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
871 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
872 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
874 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
875 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
878 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
879 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
881 IDirect3DVertexDeclaration9_Release(vertex_declaration);
882 IDirect3DVertexShader9_Release(mova_shader);
883 IDirect3DVertexShader9_Release(mov_shader);
886 struct sVertex {
887 float x, y, z;
888 DWORD diffuse;
889 DWORD specular;
892 struct sVertexT {
893 float x, y, z, rhw;
894 DWORD diffuse;
895 DWORD specular;
898 static void fog_test(IDirect3DDevice9 *device)
900 HRESULT hr;
901 D3DCOLOR color;
902 float start = 0.0f, end = 1.0f;
903 D3DCAPS9 caps;
904 int i;
906 /* Gets full z based fog with linear fog, no fog with specular color */
907 struct sVertex untransformed_1[] = {
908 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
909 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
910 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
911 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
913 /* Ok, I am too lazy to deal with transform matrices */
914 struct sVertex untransformed_2[] = {
915 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
916 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
917 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
918 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
920 /* Untransformed ones. Give them a different diffuse color to make the test look
921 * nicer. It also makes making sure that they are drawn correctly easier.
923 struct sVertexT transformed_1[] = {
924 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
925 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
926 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
927 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
929 struct sVertexT transformed_2[] = {
930 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
931 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
932 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
933 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
935 struct vertex rev_fog_quads[] = {
936 {-1.0, -1.0, 0.1, 0x000000ff},
937 {-1.0, 0.0, 0.1, 0x000000ff},
938 { 0.0, 0.0, 0.1, 0x000000ff},
939 { 0.0, -1.0, 0.1, 0x000000ff},
941 { 0.0, -1.0, 0.9, 0x000000ff},
942 { 0.0, 0.0, 0.9, 0x000000ff},
943 { 1.0, 0.0, 0.9, 0x000000ff},
944 { 1.0, -1.0, 0.9, 0x000000ff},
946 { 0.0, 0.0, 0.4, 0x000000ff},
947 { 0.0, 1.0, 0.4, 0x000000ff},
948 { 1.0, 1.0, 0.4, 0x000000ff},
949 { 1.0, 0.0, 0.4, 0x000000ff},
951 {-1.0, 0.0, 0.7, 0x000000ff},
952 {-1.0, 1.0, 0.7, 0x000000ff},
953 { 0.0, 1.0, 0.7, 0x000000ff},
954 { 0.0, 0.0, 0.7, 0x000000ff},
956 WORD Indices[] = {0, 1, 2, 2, 3, 0};
958 const float ident_mat[16] =
960 1.0f, 0.0f, 0.0f, 0.0f,
961 0.0f, 1.0f, 0.0f, 0.0f,
962 0.0f, 0.0f, 1.0f, 0.0f,
963 0.0f, 0.0f, 0.0f, 1.0f
965 const float world_mat1[16] =
967 1.0f, 0.0f, 0.0f, 0.0f,
968 0.0f, 1.0f, 0.0f, 0.0f,
969 0.0f, 0.0f, 1.0f, 0.0f,
970 0.0f, 0.0f, -0.5f, 1.0f
972 const float world_mat2[16] =
974 1.0f, 0.0f, 0.0f, 0.0f,
975 0.0f, 1.0f, 0.0f, 0.0f,
976 0.0f, 0.0f, 1.0f, 0.0f,
977 0.0f, 0.0f, 1.0f, 1.0f
979 const float proj_mat[16] =
981 1.0f, 0.0f, 0.0f, 0.0f,
982 0.0f, 1.0f, 0.0f, 0.0f,
983 0.0f, 0.0f, 1.0f, 0.0f,
984 0.0f, 0.0f, -1.0f, 1.0f
987 const struct sVertex far_quad1[] =
989 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
990 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
991 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
992 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
994 const struct sVertex far_quad2[] =
996 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
997 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
998 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
999 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1002 memset(&caps, 0, sizeof(caps));
1003 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1004 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1006 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1008 /* Setup initial states: No lighting, fog on, fog color */
1009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1010 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1012 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1014 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1016 /* First test: Both table fog and vertex fog off */
1017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1018 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1020 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1022 /* Start = 0, end = 1. Should be default, but set them */
1023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1024 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1026 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1028 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1030 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1031 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1032 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1033 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1034 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1035 sizeof(untransformed_1[0]));
1036 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1038 /* That makes it use the Z value */
1039 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1040 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1041 /* Untransformed, vertex fog != none (or table fog != none):
1042 * Use the Z value as input into the equation
1044 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1045 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1046 sizeof(untransformed_2[0]));
1047 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1049 /* transformed verts */
1050 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1051 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1052 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1053 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1055 sizeof(transformed_1[0]));
1056 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1061 * equation
1063 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1064 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1065 sizeof(transformed_2[0]));
1066 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1068 hr = IDirect3DDevice9_EndScene(device);
1069 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1071 else
1073 ok(FALSE, "BeginScene failed\n");
1076 color = getPixelColor(device, 160, 360);
1077 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1078 color = getPixelColor(device, 160, 120);
1079 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1080 color = getPixelColor(device, 480, 120);
1081 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1082 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1084 color = getPixelColor(device, 480, 360);
1085 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1087 else
1089 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1090 * The settings above result in no fogging with vertex fog
1092 color = getPixelColor(device, 480, 120);
1093 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1094 trace("Info: Table fog not supported by this device\n");
1096 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1098 /* Now test the special case fogstart == fogend */
1099 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1100 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1102 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1104 start = 512;
1105 end = 512;
1106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1107 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1109 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1111 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1112 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1114 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1116 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1118 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1119 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1120 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1121 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1122 * color and has fixed fogstart and fogend.
1124 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1125 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1126 sizeof(untransformed_1[0]));
1127 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1128 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1129 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1130 sizeof(untransformed_2[0]));
1131 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1133 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1134 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1135 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1136 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1137 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1138 sizeof(transformed_1[0]));
1139 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1141 hr = IDirect3DDevice9_EndScene(device);
1142 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1144 else
1146 ok(FALSE, "BeginScene failed\n");
1148 color = getPixelColor(device, 160, 360);
1149 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1150 color = getPixelColor(device, 160, 120);
1151 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1152 color = getPixelColor(device, 480, 120);
1153 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1154 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1156 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1157 * but without shaders it seems to work everywhere
1159 end = 0.2;
1160 start = 0.8;
1161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1162 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1164 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1165 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1166 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1168 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1169 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1170 * so skip this for now
1172 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1173 const char *mode = (i ? "table" : "vertex");
1174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1175 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1177 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1179 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1180 hr = IDirect3DDevice9_BeginScene(device);
1181 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1182 if(SUCCEEDED(hr)) {
1183 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1184 4, 5, 6, 6, 7, 4,
1185 8, 9, 10, 10, 11, 8,
1186 12, 13, 14, 14, 15, 12};
1188 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1189 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1190 sizeof(rev_fog_quads[0]));
1191 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1193 hr = IDirect3DDevice9_EndScene(device);
1194 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1196 color = getPixelColor(device, 160, 360);
1197 ok(color_match(color, 0x0000ff00, 1),
1198 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1200 color = getPixelColor(device, 160, 120);
1201 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1202 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1204 color = getPixelColor(device, 480, 120);
1205 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1206 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1208 color = getPixelColor(device, 480, 360);
1209 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1211 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1213 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1214 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1215 break;
1219 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1221 /* A simple fog + non-identity world matrix test */
1222 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1223 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1225 start = 0.0;
1226 end = 1.0;
1227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1228 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1230 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1232 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1234 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1237 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1239 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1241 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1242 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1244 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1245 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1246 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1248 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1249 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1250 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1252 hr = IDirect3DDevice9_EndScene(device);
1253 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1255 else
1257 ok(FALSE, "BeginScene failed\n");
1260 color = getPixelColor(device, 160, 360);
1261 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1262 "Unfogged quad has color %08x\n", color);
1263 color = getPixelColor(device, 160, 120);
1264 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1265 "Fogged out quad has color %08x\n", color);
1267 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1269 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1270 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1271 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1272 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1273 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1276 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1278 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1280 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1281 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1283 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1285 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1287 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1288 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1289 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1291 hr = IDirect3DDevice9_EndScene(device);
1292 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1294 else
1296 ok(FALSE, "BeginScene failed\n");
1299 color = getPixelColor(device, 160, 360);
1300 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1301 color = getPixelColor(device, 160, 120);
1302 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1303 "Fogged out quad has color %08x\n", color);
1305 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1307 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1308 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1309 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1310 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1312 else
1314 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1317 /* Test RANGEFOG vs FOGTABLEMODE */
1318 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1319 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1321 struct sVertex untransformed_3[] =
1323 {-1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1324 {-1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1325 { 1.0,-1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1326 { 1.0, 1.0, 0.4999f, 0xFFFF0000, 0xFF000000 },
1329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1330 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1331 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1332 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1335 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1337 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1338 * is not used, the fog coordinate will be equal to fogstart and the quad not
1339 * fogged. If range fog is used the fog coordinate will be slightly higher and
1340 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1341 * is calculated per vertex and interpolated, so even the center of the screen
1342 * where the difference doesn't matter will be fogged, but check the corners in
1343 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1344 start = 0.5f;
1345 end = 0.50001f;
1346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1347 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1349 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1351 /* Table fog: Range fog is not used */
1352 hr = IDirect3DDevice9_BeginScene(device);
1353 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1354 if (SUCCEEDED(hr))
1356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1357 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1359 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1360 hr = IDirect3DDevice9_EndScene(device);
1361 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1363 color = getPixelColor(device, 10, 10);
1364 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1365 color = getPixelColor(device, 630, 10);
1366 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1367 color = getPixelColor(device, 10, 470);
1368 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1369 color = getPixelColor(device, 630, 470);
1370 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1372 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1373 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1375 /* Vertex fog: Rangefog is used */
1376 hr = IDirect3DDevice9_BeginScene(device);
1377 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1378 if (SUCCEEDED(hr))
1380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1381 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1385 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1386 hr = IDirect3DDevice9_EndScene(device);
1387 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1389 color = getPixelColor(device, 10, 10);
1390 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1391 "Rangefog with vertex fog returned color 0x%08x\n", color);
1392 color = getPixelColor(device, 630, 10);
1393 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1394 "Rangefog with vertex fog returned color 0x%08x\n", color);
1395 color = getPixelColor(device, 10, 470);
1396 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1397 "Rangefog with vertex fog returned color 0x%08x\n", color);
1398 color = getPixelColor(device, 630, 470);
1399 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1400 "Rangefog with vertex fog returned color 0x%08x\n", color);
1402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1403 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1406 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1408 else
1410 skip("Range fog or table fog not supported, skipping range fog tests\n");
1413 /* Turn off the fog master switch to avoid confusing other tests */
1414 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1415 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1417 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1419 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1422 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1423 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1424 * regardless of the actual addressing mode set. The way this test works is
1425 * that we sample in one of the corners of the cubemap with filtering enabled,
1426 * and check the interpolated color. There are essentially two reasonable
1427 * things an implementation can do: Either pick one of the faces and
1428 * interpolate the edge texel with itself (i.e., clamp within the face), or
1429 * interpolate between the edge texels of the three involved faces. It should
1430 * never involve the border color or the other side (texcoord wrapping) of a
1431 * face in the interpolation. */
1432 static void test_cube_wrap(IDirect3DDevice9 *device)
1434 static const float quad[][6] = {
1435 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1436 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1437 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1438 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1441 static const D3DVERTEXELEMENT9 decl_elements[] = {
1442 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1443 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1444 D3DDECL_END()
1447 static const struct {
1448 D3DTEXTUREADDRESS mode;
1449 const char *name;
1450 } address_modes[] = {
1451 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1452 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1453 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1454 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1455 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1458 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1459 IDirect3DCubeTexture9 *texture = NULL;
1460 IDirect3DSurface9 *surface = NULL;
1461 IDirect3DSurface9 *face_surface;
1462 D3DLOCKED_RECT locked_rect;
1463 HRESULT hr;
1464 UINT x;
1465 INT y, face;
1467 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1468 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1469 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1470 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1472 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1473 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1474 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1476 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1477 D3DPOOL_DEFAULT, &texture, NULL);
1478 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1480 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1481 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1483 for (y = 0; y < 128; ++y)
1485 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1486 for (x = 0; x < 64; ++x)
1488 *ptr++ = 0xff0000ff;
1490 for (x = 64; x < 128; ++x)
1492 *ptr++ = 0xffff0000;
1496 hr = IDirect3DSurface9_UnlockRect(surface);
1497 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1499 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1500 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1502 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1503 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1505 IDirect3DSurface9_Release(face_surface);
1507 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1508 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1510 for (y = 0; y < 128; ++y)
1512 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1513 for (x = 0; x < 64; ++x)
1515 *ptr++ = 0xffff0000;
1517 for (x = 64; x < 128; ++x)
1519 *ptr++ = 0xff0000ff;
1523 hr = IDirect3DSurface9_UnlockRect(surface);
1524 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1526 /* Create cube faces */
1527 for (face = 1; face < 6; ++face)
1529 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1530 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1532 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1533 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1535 IDirect3DSurface9_Release(face_surface);
1538 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1539 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1541 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1542 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1543 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1544 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1545 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1546 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1551 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1553 DWORD color;
1555 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1556 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1557 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1558 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1560 hr = IDirect3DDevice9_BeginScene(device);
1561 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1564 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1566 hr = IDirect3DDevice9_EndScene(device);
1567 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1569 color = getPixelColor(device, 320, 240);
1570 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1571 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1572 color, address_modes[x].name);
1574 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1575 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1577 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1578 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1581 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1582 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1584 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1585 IDirect3DCubeTexture9_Release(texture);
1586 IDirect3DSurface9_Release(surface);
1589 static void offscreen_test(IDirect3DDevice9 *device)
1591 HRESULT hr;
1592 IDirect3DTexture9 *offscreenTexture = NULL;
1593 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1594 DWORD color;
1596 static const float quad[][5] = {
1597 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1598 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1599 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1600 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1603 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1604 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1606 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1607 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1608 if(!offscreenTexture) {
1609 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1610 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1611 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1612 if(!offscreenTexture) {
1613 skip("Cannot create an offscreen render target\n");
1614 goto out;
1618 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1619 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1620 if(!backbuffer) {
1621 goto out;
1624 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1625 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1626 if(!offscreen) {
1627 goto out;
1630 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1631 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1633 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1634 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1635 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1636 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1637 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1638 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1639 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1640 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1642 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1644 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1645 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1646 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1648 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1650 /* Draw without textures - Should result in a white quad */
1651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1652 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1654 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1655 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1656 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1657 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1659 /* This time with the texture */
1660 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1661 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1663 IDirect3DDevice9_EndScene(device);
1666 /* Center quad - should be white */
1667 color = getPixelColor(device, 320, 240);
1668 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669 /* Some quad in the cleared part of the texture */
1670 color = getPixelColor(device, 170, 240);
1671 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1672 /* Part of the originally cleared back buffer */
1673 color = getPixelColor(device, 10, 10);
1674 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1675 if(0) {
1676 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1677 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1678 * the offscreen rendering mode this test would succeed or fail
1680 color = getPixelColor(device, 10, 470);
1681 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1684 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1686 out:
1687 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1688 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1690 /* restore things */
1691 if (backbuffer)
1693 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1694 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1695 IDirect3DSurface9_Release(backbuffer);
1697 if(offscreenTexture) {
1698 IDirect3DTexture9_Release(offscreenTexture);
1700 if(offscreen) {
1701 IDirect3DSurface9_Release(offscreen);
1705 /* This test tests fog in combination with shaders.
1706 * What's tested: linear fog (vertex and table) with pixel shader
1707 * linear table fog with non foggy vertex shader
1708 * vertex fog with foggy vertex shader, non-linear
1709 * fog with shader, non-linear fog with foggy shader,
1710 * linear table fog with foggy shader
1712 static void fog_with_shader_test(IDirect3DDevice9 *device)
1714 HRESULT hr;
1715 DWORD color;
1716 union {
1717 float f;
1718 DWORD i;
1719 } start, end;
1720 unsigned int i, j;
1722 /* basic vertex shader without fog computation ("non foggy") */
1723 static const DWORD vertex_shader_code1[] =
1725 0xfffe0101, /* vs_1_1 */
1726 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1727 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1728 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1729 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1730 0x0000ffff
1732 /* basic vertex shader with reversed fog computation ("foggy") */
1733 static const DWORD vertex_shader_code2[] =
1735 0xfffe0101, /* vs_1_1 */
1736 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1737 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1738 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1739 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1740 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1741 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1742 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1743 0x0000ffff
1745 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1746 static const DWORD vertex_shader_code3[] =
1748 0xfffe0200, /* vs_2_0 */
1749 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1750 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1751 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1752 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1753 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1754 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1755 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1756 0x0000ffff
1758 /* basic pixel shader */
1759 static const DWORD pixel_shader_code[] =
1761 0xffff0101, /* ps_1_1 */
1762 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1763 0x0000ffff
1765 static const DWORD pixel_shader_code2[] =
1767 0xffff0200, /* ps_2_0 */
1768 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
1769 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
1770 0x0000ffff
1773 static struct vertex quad[] = {
1774 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1775 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1776 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1777 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1780 static const D3DVERTEXELEMENT9 decl_elements[] = {
1781 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1782 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1783 D3DDECL_END()
1786 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1787 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
1788 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
1790 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1791 static const struct test_data_t {
1792 int vshader;
1793 int pshader;
1794 D3DFOGMODE vfog;
1795 D3DFOGMODE tfog;
1796 unsigned int color[11];
1797 } test_data[] = {
1798 /* only pixel shader: */
1799 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1800 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1801 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1802 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1803 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1806 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1815 /* vertex shader */
1816 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1817 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1818 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1819 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1820 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1823 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1826 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1827 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1830 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1833 /* vertex shader and pixel shader */
1834 /* The next 4 tests would read the fog coord output, but it isn't available.
1835 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1836 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1837 * These tests should be disabled if some other hardware behaves differently
1839 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1840 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1841 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1842 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1843 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1844 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1845 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1846 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1847 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1848 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1850 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1852 /* These use the Z coordinate with linear table fog */
1853 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1854 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1857 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1859 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1860 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1861 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1862 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1863 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1864 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1866 /* Non-linear table fog without fog coord */
1867 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1868 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1869 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1870 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1871 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1872 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1874 /* These tests fail on older Nvidia drivers */
1875 /* foggy vertex shader */
1876 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1877 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1878 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1879 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1880 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1881 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1882 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1883 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1884 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1885 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1886 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1887 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1889 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1890 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1891 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1892 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1893 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1894 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1895 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1896 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1897 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1898 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1899 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1900 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1902 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1903 * all using the fixed fog-coord linear fog
1905 /* vs_1_1 with ps_1_1 */
1906 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1907 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1910 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1913 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1915 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1916 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1917 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1919 /* vs_2_0 with ps_1_1 */
1920 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1921 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1922 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1923 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1924 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1925 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1926 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1927 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1928 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1929 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1930 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1931 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1933 /* vs_1_1 with ps_2_0 */
1934 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1935 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1936 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1937 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1938 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1939 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1940 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1941 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1942 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1943 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1944 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1945 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1947 /* vs_2_0 with ps_2_0 */
1948 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1949 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1950 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1951 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1952 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1953 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1954 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1955 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1956 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1957 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1958 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1959 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1961 /* These use table fog. Here the shader-provided fog coordinate is
1962 * ignored and the z coordinate used instead
1964 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1965 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1966 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1967 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1968 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1969 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1970 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1971 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1972 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1975 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1976 start.f=0.1f;
1977 end.f=0.9f;
1979 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1980 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1981 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1982 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1983 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
1984 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1985 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1986 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1987 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
1988 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1989 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1990 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1992 /* Setup initial states: No lighting, fog on, fog color */
1993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1994 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1996 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1998 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1999 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2000 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2002 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2003 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2004 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2005 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2007 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2009 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2011 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2013 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2015 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2016 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2017 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2018 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2020 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2022 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2024 for(j=0; j < 11; j++)
2026 /* Don't use the whole zrange to prevent rounding errors */
2027 quad[0].z = 0.001f + (float)j / 10.02f;
2028 quad[1].z = 0.001f + (float)j / 10.02f;
2029 quad[2].z = 0.001f + (float)j / 10.02f;
2030 quad[3].z = 0.001f + (float)j / 10.02f;
2032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2035 hr = IDirect3DDevice9_BeginScene(device);
2036 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2039 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2041 hr = IDirect3DDevice9_EndScene(device);
2042 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2044 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2045 color = getPixelColor(device, 128, 240);
2046 ok(color_match(color, test_data[i].color[j], 13),
2047 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2048 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2050 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2054 /* reset states */
2055 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2056 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2057 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2058 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2059 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2060 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2062 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2064 IDirect3DVertexShader9_Release(vertex_shader[1]);
2065 IDirect3DVertexShader9_Release(vertex_shader[2]);
2066 IDirect3DVertexShader9_Release(vertex_shader[3]);
2067 IDirect3DPixelShader9_Release(pixel_shader[1]);
2068 IDirect3DPixelShader9_Release(pixel_shader[2]);
2069 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2072 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2073 unsigned int i, x, y;
2074 HRESULT hr;
2075 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2076 D3DLOCKED_RECT locked_rect;
2078 /* Generate the textures */
2079 for(i=0; i<2; i++)
2081 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2082 D3DPOOL_MANAGED, &texture[i], NULL);
2083 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2085 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2086 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2087 for (y = 0; y < 128; ++y)
2089 if(i)
2090 { /* Set up black texture with 2x2 texel white spot in the middle */
2091 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2092 for (x = 0; x < 128; ++x)
2094 if(y>62 && y<66 && x>62 && x<66)
2095 *ptr++ = 0xffffffff;
2096 else
2097 *ptr++ = 0xff000000;
2100 else
2101 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2102 * (if multiplied with bumpenvmat)
2104 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2105 for (x = 0; x < 128; ++x)
2107 if(abs(x-64)>abs(y-64))
2109 if(x < 64)
2110 *ptr++ = 0xc000;
2111 else
2112 *ptr++ = 0x4000;
2114 else
2116 if(y < 64)
2117 *ptr++ = 0x0040;
2118 else
2119 *ptr++ = 0x00c0;
2124 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2125 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2127 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2128 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2130 /* Disable texture filtering */
2131 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2132 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2133 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2134 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2136 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2137 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2138 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2139 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2143 /* test the behavior of the texbem instruction
2144 * with normal 2D and projective 2D textures
2146 static void texbem_test(IDirect3DDevice9 *device)
2148 HRESULT hr;
2149 DWORD color;
2150 int i;
2152 static const DWORD pixel_shader_code[] = {
2153 0xffff0101, /* ps_1_1*/
2154 0x00000042, 0xb00f0000, /* tex t0*/
2155 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2156 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2157 0x0000ffff
2159 static const DWORD double_texbem_code[] = {
2160 0xffff0103, /* ps_1_3 */
2161 0x00000042, 0xb00f0000, /* tex t0 */
2162 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2163 0x00000042, 0xb00f0002, /* tex t2 */
2164 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2165 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2166 0x0000ffff /* end */
2170 static const float quad[][7] = {
2171 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2172 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2173 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2174 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2176 static const float quad_proj[][9] = {
2177 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2178 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2179 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2180 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2183 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2184 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2185 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2186 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2187 D3DDECL_END()
2189 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2190 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2191 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2192 D3DDECL_END()
2193 } };
2195 /* use asymmetric matrix to test loading */
2196 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2198 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2199 IDirect3DPixelShader9 *pixel_shader = NULL;
2200 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
2201 D3DLOCKED_RECT locked_rect;
2203 generate_bumpmap_textures(device);
2205 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2206 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2207 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2208 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2209 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2211 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2212 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2215 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2217 for(i=0; i<2; i++)
2219 if(i)
2221 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2222 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2225 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2226 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2227 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2228 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2230 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2231 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2232 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2233 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2235 hr = IDirect3DDevice9_BeginScene(device);
2236 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2238 if(!i)
2239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2240 else
2241 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2242 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2244 hr = IDirect3DDevice9_EndScene(device);
2245 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2247 color = getPixelColor(device, 320-32, 240);
2248 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2249 color = getPixelColor(device, 320+32, 240);
2250 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2251 color = getPixelColor(device, 320, 240-32);
2252 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2253 color = getPixelColor(device, 320, 240+32);
2254 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2257 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2259 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2260 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2261 IDirect3DPixelShader9_Release(pixel_shader);
2263 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2264 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2265 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2268 /* clean up */
2269 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2270 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2272 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2273 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2275 for(i=0; i<2; i++)
2277 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2278 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2279 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2280 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2281 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2282 IDirect3DTexture9_Release(texture);
2285 /* Test double texbem */
2286 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2287 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2288 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2289 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2290 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2291 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2292 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2293 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2295 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2296 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2297 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2298 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2300 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2301 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2303 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2304 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2305 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2306 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2307 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2308 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2311 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2312 #define tex 0x00ff0000
2313 #define tex1 0x0000ff00
2314 #define origin 0x000000ff
2315 static const DWORD pixel_data[] = {
2316 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2317 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2318 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2319 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2320 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2321 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2322 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2323 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2325 #undef tex1
2326 #undef tex2
2327 #undef origin
2329 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2330 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2331 for(i = 0; i < 8; i++) {
2332 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2334 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2335 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2338 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2339 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2340 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2341 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2342 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2343 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2344 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2345 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2346 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2347 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2348 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2349 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2351 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2352 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2353 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2355 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2356 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2357 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2358 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2359 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2360 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2362 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2363 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2364 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2365 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2366 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2367 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2368 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2369 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2370 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2371 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2373 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2374 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2376 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2377 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2378 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2379 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2380 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2381 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2382 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2383 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2384 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2385 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2386 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2387 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2388 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2390 hr = IDirect3DDevice9_BeginScene(device);
2391 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2392 if(SUCCEEDED(hr)) {
2393 static const float double_quad[] = {
2394 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2395 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2396 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2397 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2401 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2402 hr = IDirect3DDevice9_EndScene(device);
2403 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2405 color = getPixelColor(device, 320, 240);
2406 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2408 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2409 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2410 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2411 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2412 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2413 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2414 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2415 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2416 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2417 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2419 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2420 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2422 IDirect3DPixelShader9_Release(pixel_shader);
2423 IDirect3DTexture9_Release(texture);
2424 IDirect3DTexture9_Release(texture1);
2425 IDirect3DTexture9_Release(texture2);
2428 static void z_range_test(IDirect3DDevice9 *device)
2430 const struct vertex quad[] =
2432 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2433 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2434 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2435 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2437 const struct vertex quad2[] =
2439 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2440 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2441 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2442 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2445 const struct tvertex quad3[] =
2447 { 0, 240, 1.1f, 1.0, 0xffffff00},
2448 { 0, 480, 1.1f, 1.0, 0xffffff00},
2449 { 640, 240, -1.1f, 1.0, 0xffffff00},
2450 { 640, 480, -1.1f, 1.0, 0xffffff00},
2452 const struct tvertex quad4[] =
2454 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2455 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2456 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2457 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2459 HRESULT hr;
2460 DWORD color;
2461 IDirect3DVertexShader9 *shader;
2462 IDirect3DVertexDeclaration9 *decl;
2463 D3DCAPS9 caps;
2464 const DWORD shader_code[] = {
2465 0xfffe0101, /* vs_1_1 */
2466 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2467 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2468 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2469 0x0000ffff /* end */
2471 static const D3DVERTEXELEMENT9 decl_elements[] = {
2472 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2473 D3DDECL_END()
2476 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2478 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2479 * then call Present. Then clear the color buffer to make sure it has some defined content
2480 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2481 * by the depth value.
2483 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2484 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2485 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2486 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2487 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2488 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2491 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2493 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2495 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2497 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2498 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2499 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF 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 /* Test the untransformed vertex path */
2506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2507 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2509 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2511 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2513 /* Test the transformed vertex path */
2514 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2515 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2518 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2520 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2522 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2524 hr = IDirect3DDevice9_EndScene(device);
2525 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2528 /* Do not test the exact corner pixels, but go pretty close to them */
2530 /* Clipped because z > 1.0 */
2531 color = getPixelColor(device, 28, 238);
2532 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2533 color = getPixelColor(device, 28, 241);
2534 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2536 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2538 else
2540 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2543 /* Not clipped, > z buffer clear value(0.75) */
2544 color = getPixelColor(device, 31, 238);
2545 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2546 color = getPixelColor(device, 31, 241);
2547 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2548 color = getPixelColor(device, 100, 238);
2549 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2550 color = getPixelColor(device, 100, 241);
2551 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2553 /* Not clipped, < z buffer clear value */
2554 color = getPixelColor(device, 104, 238);
2555 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2556 color = getPixelColor(device, 104, 241);
2557 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2558 color = getPixelColor(device, 318, 238);
2559 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2560 color = getPixelColor(device, 318, 241);
2561 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2563 /* Clipped because z < 0.0 */
2564 color = getPixelColor(device, 321, 238);
2565 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2566 color = getPixelColor(device, 321, 241);
2567 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2569 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2571 else
2573 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2577 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2579 /* Test the shader path */
2580 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2581 skip("Vertex shaders not supported\n");
2582 goto out;
2584 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2585 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2586 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2587 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2589 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2591 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2592 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2593 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2594 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2596 hr = IDirect3DDevice9_BeginScene(device);
2597 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2598 if(hr == D3D_OK)
2600 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2601 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2602 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2604 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2606 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2607 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2609 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2611 hr = IDirect3DDevice9_EndScene(device);
2612 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2615 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2616 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2617 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2618 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2620 IDirect3DVertexDeclaration9_Release(decl);
2621 IDirect3DVertexShader9_Release(shader);
2623 /* Z < 1.0 */
2624 color = getPixelColor(device, 28, 238);
2625 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2627 /* 1.0 < z < 0.75 */
2628 color = getPixelColor(device, 31, 238);
2629 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2630 color = getPixelColor(device, 100, 238);
2631 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2633 /* 0.75 < z < 0.0 */
2634 color = getPixelColor(device, 104, 238);
2635 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2636 color = getPixelColor(device, 318, 238);
2637 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2639 /* 0.0 < z */
2640 color = getPixelColor(device, 321, 238);
2641 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2643 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2644 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2646 out:
2647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2652 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2655 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2657 D3DSURFACE_DESC desc;
2658 D3DLOCKED_RECT l;
2659 HRESULT hr;
2660 unsigned int x, y;
2661 DWORD *mem;
2663 memset(&desc, 0, sizeof(desc));
2664 memset(&l, 0, sizeof(l));
2665 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2666 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2667 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2668 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2669 if(FAILED(hr)) return;
2671 for(y = 0; y < desc.Height; y++)
2673 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2674 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2676 mem[x] = color;
2679 hr = IDirect3DSurface9_UnlockRect(surface);
2680 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2683 /* This tests a variety of possible StretchRect() situations */
2684 static void stretchrect_test(IDirect3DDevice9 *device)
2686 HRESULT hr;
2687 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2688 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2689 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2690 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2691 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2692 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2693 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2694 IDirect3DSurface9 *orig_rt = NULL;
2695 IDirect3DSurface9 *backbuffer = NULL;
2696 DWORD color;
2698 RECT src_rect64 = {0, 0, 64, 64};
2699 RECT src_rect64_flipy = {0, 64, 64, 0};
2700 RECT dst_rect64 = {0, 0, 64, 64};
2701 RECT dst_rect64_flipy = {0, 64, 64, 0};
2703 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2704 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2705 if(!orig_rt) {
2706 goto out;
2709 /* Create our temporary surfaces in system memory */
2710 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2711 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2712 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2713 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2715 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2716 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2717 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2718 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2719 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2720 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2721 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2723 /* Create render target surfaces */
2724 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2725 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2726 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2727 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2728 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2729 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2730 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2731 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2733 /* Create render target textures */
2734 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2735 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2736 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2737 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2738 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2739 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2740 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2741 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2742 if (tex_rt32) {
2743 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2744 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2746 if (tex_rt64) {
2747 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2748 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2750 if (tex_rt_dest64) {
2751 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2752 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2754 if (tex_rt_dest64) {
2755 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2756 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2759 /* Create regular textures in D3DPOOL_DEFAULT */
2760 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2761 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2762 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2763 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2764 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2765 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2766 if (tex32) {
2767 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2768 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2770 if (tex64) {
2771 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2772 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2774 if (tex_dest64) {
2775 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2776 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2779 /*********************************************************************
2780 * Tests for when the source parameter is an offscreen plain surface *
2781 *********************************************************************/
2783 /* Fill the offscreen 64x64 surface with green */
2784 if (surf_offscreen64)
2785 fill_surface(surf_offscreen64, 0xff00ff00);
2787 /* offscreenplain ==> offscreenplain, same size */
2788 if(surf_offscreen64 && surf_offscreen_dest64) {
2789 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2790 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792 if (hr == D3D_OK) {
2793 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2794 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2797 /* Blit without scaling */
2798 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2799 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2801 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2802 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2803 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2805 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2806 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2807 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2810 /* offscreenplain ==> rendertarget texture, same size */
2811 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2812 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2813 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815 /* We can't lock rendertarget textures, so copy to our temp surface first */
2816 if (hr == D3D_OK) {
2817 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2818 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2821 if (hr == D3D_OK) {
2822 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2823 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2826 /* Blit without scaling */
2827 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2828 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2831 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2832 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2835 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2836 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2839 /* offscreenplain ==> rendertarget surface, same size */
2840 if(surf_offscreen64 && surf_rt_dest64) {
2841 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2842 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2844 if (hr == D3D_OK) {
2845 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2846 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2849 /* Blit without scaling */
2850 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2851 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2853 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2854 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2855 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2857 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2858 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2859 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2862 /* offscreenplain ==> texture, same size (should fail) */
2863 if(surf_offscreen64 && surf_tex_dest64) {
2864 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2865 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2868 /* Fill the smaller offscreen surface with red */
2869 fill_surface(surf_offscreen32, 0xffff0000);
2871 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2872 if(surf_offscreen32 && surf_offscreen64) {
2873 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2874 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2877 /* offscreenplain ==> rendertarget texture, scaling */
2878 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2879 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2880 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2882 /* We can't lock rendertarget textures, so copy to our temp surface first */
2883 if (hr == D3D_OK) {
2884 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2885 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2888 if (hr == D3D_OK) {
2889 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2890 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2894 /* offscreenplain ==> rendertarget surface, scaling */
2895 if(surf_offscreen32 && surf_rt_dest64) {
2896 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2897 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2899 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2900 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2903 /* offscreenplain ==> texture, scaling (should fail) */
2904 if(surf_offscreen32 && surf_tex_dest64) {
2905 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2906 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2909 /************************************************************
2910 * Tests for when the source parameter is a regular texture *
2911 ************************************************************/
2913 /* Fill the surface of the regular texture with blue */
2914 if (surf_tex64 && surf_temp64) {
2915 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2916 fill_surface(surf_temp64, 0xff0000ff);
2917 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2918 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2921 /* texture ==> offscreenplain, same size */
2922 if(surf_tex64 && surf_offscreen64) {
2923 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2924 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2927 /* texture ==> rendertarget texture, same size */
2928 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2929 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2930 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2932 /* We can't lock rendertarget textures, so copy to our temp surface first */
2933 if (hr == D3D_OK) {
2934 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2935 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2938 if (hr == D3D_OK) {
2939 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2940 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2943 /* Blit without scaling */
2944 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2945 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2947 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2948 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2949 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2951 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2952 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2953 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2956 /* texture ==> rendertarget surface, same size */
2957 if(surf_tex64 && surf_rt_dest64) {
2958 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2959 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2961 if (hr == D3D_OK) {
2962 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2963 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2966 /* Blit without scaling */
2967 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2968 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2970 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2971 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2972 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2974 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2975 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2976 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2979 /* texture ==> texture, same size (should fail) */
2980 if(surf_tex64 && surf_tex_dest64) {
2981 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2982 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2985 /* Fill the surface of the smaller regular texture with red */
2986 if (surf_tex32 && surf_temp32) {
2987 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2988 fill_surface(surf_temp32, 0xffff0000);
2989 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2990 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2993 /* texture ==> offscreenplain, scaling (should fail) */
2994 if(surf_tex32 && surf_offscreen64) {
2995 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2996 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2999 /* texture ==> rendertarget texture, scaling */
3000 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3001 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3002 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3004 /* We can't lock rendertarget textures, so copy to our temp surface first */
3005 if (hr == D3D_OK) {
3006 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3007 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3010 if (hr == D3D_OK) {
3011 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3012 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3016 /* texture ==> rendertarget surface, scaling */
3017 if(surf_tex32 && surf_rt_dest64) {
3018 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3019 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3021 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3022 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3025 /* texture ==> texture, scaling (should fail) */
3026 if(surf_tex32 && surf_tex_dest64) {
3027 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3028 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3031 /*****************************************************************
3032 * Tests for when the source parameter is a rendertarget texture *
3033 *****************************************************************/
3035 /* Fill the surface of the rendertarget texture with white */
3036 if (surf_tex_rt64 && surf_temp64) {
3037 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3038 fill_surface(surf_temp64, 0xffffffff);
3039 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3040 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3043 /* rendertarget texture ==> offscreenplain, same size */
3044 if(surf_tex_rt64 && surf_offscreen64) {
3045 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3046 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3049 /* rendertarget texture ==> rendertarget texture, same size */
3050 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3051 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3052 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3054 /* We can't lock rendertarget textures, so copy to our temp surface first */
3055 if (hr == D3D_OK) {
3056 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3057 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3060 if (hr == D3D_OK) {
3061 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3062 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3065 /* Blit without scaling */
3066 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3067 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3069 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3070 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3071 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3073 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3074 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3075 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3078 /* rendertarget texture ==> rendertarget surface, same size */
3079 if(surf_tex_rt64 && surf_rt_dest64) {
3080 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3081 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3083 if (hr == D3D_OK) {
3084 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3085 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3088 /* Blit without scaling */
3089 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_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_tex_rt64, &src_rect64_flipy, surf_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_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3098 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3101 /* rendertarget texture ==> texture, same size (should fail) */
3102 if(surf_tex_rt64 && surf_tex_dest64) {
3103 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3104 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3107 /* Fill the surface of the smaller rendertarget texture with red */
3108 if (surf_tex_rt32 && surf_temp32) {
3109 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3110 fill_surface(surf_temp32, 0xffff0000);
3111 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3112 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3115 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3116 if(surf_tex_rt32 && surf_offscreen64) {
3117 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3118 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3121 /* rendertarget texture ==> rendertarget texture, scaling */
3122 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3123 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3124 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3126 /* We can't lock rendertarget textures, so copy to our temp surface first */
3127 if (hr == D3D_OK) {
3128 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3129 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3132 if (hr == D3D_OK) {
3133 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3134 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3138 /* rendertarget texture ==> rendertarget surface, scaling */
3139 if(surf_tex_rt32 && surf_rt_dest64) {
3140 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3141 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3143 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3144 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3147 /* rendertarget texture ==> texture, scaling (should fail) */
3148 if(surf_tex_rt32 && surf_tex_dest64) {
3149 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3150 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3153 /*****************************************************************
3154 * Tests for when the source parameter is a rendertarget surface *
3155 *****************************************************************/
3157 /* Fill the surface of the rendertarget surface with black */
3158 if (surf_rt64)
3159 fill_surface(surf_rt64, 0xff000000);
3161 /* rendertarget texture ==> offscreenplain, same size */
3162 if(surf_rt64 && surf_offscreen64) {
3163 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3164 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3167 /* rendertarget surface ==> rendertarget texture, same size */
3168 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3169 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3170 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3172 /* We can't lock rendertarget textures, so copy to our temp surface first */
3173 if (hr == D3D_OK) {
3174 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3175 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3178 if (hr == D3D_OK) {
3179 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3180 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3183 /* Blit without scaling */
3184 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3185 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3187 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3188 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3189 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3191 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3192 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3193 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3196 /* rendertarget surface ==> rendertarget surface, same size */
3197 if(surf_rt64 && surf_rt_dest64) {
3198 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3199 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3201 if (hr == D3D_OK) {
3202 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3203 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3206 /* Blit without scaling */
3207 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3208 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3210 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3211 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3212 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3214 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3215 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3216 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3219 /* rendertarget surface ==> texture, same size (should fail) */
3220 if(surf_rt64 && surf_tex_dest64) {
3221 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3222 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3225 /* Fill the surface of the smaller rendertarget texture with red */
3226 if (surf_rt32)
3227 fill_surface(surf_rt32, 0xffff0000);
3229 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3230 if(surf_rt32 && surf_offscreen64) {
3231 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3232 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3235 /* rendertarget surface ==> rendertarget texture, scaling */
3236 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3237 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3238 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3240 /* We can't lock rendertarget textures, so copy to our temp surface first */
3241 if (hr == D3D_OK) {
3242 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3243 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3246 if (hr == D3D_OK) {
3247 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3248 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3252 /* rendertarget surface ==> rendertarget surface, scaling */
3253 if(surf_rt32 && surf_rt_dest64) {
3254 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3255 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3257 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3258 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3261 /* rendertarget surface ==> texture, scaling (should fail) */
3262 if(surf_rt32 && surf_tex_dest64) {
3263 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3264 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3267 /* backbuffer ==> surface tests (no scaling) */
3268 if(backbuffer && surf_tex_rt_dest640_480)
3270 RECT src_rect = {0, 0, 640, 480};
3271 RECT src_rect_flipy = {0, 480, 640, 0};
3272 RECT dst_rect = {0, 0, 640, 480};
3273 RECT dst_rect_flipy = {0, 480, 640, 0};
3275 /* Blit with NULL rectangles */
3276 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3277 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3279 /* Blit without scaling */
3280 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3281 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3283 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3284 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3285 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3287 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3288 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3289 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3292 /* TODO: Test format conversions */
3295 out:
3296 /* Clean up */
3297 if (backbuffer)
3298 IDirect3DSurface9_Release(backbuffer);
3299 if (surf_rt32)
3300 IDirect3DSurface9_Release(surf_rt32);
3301 if (surf_rt64)
3302 IDirect3DSurface9_Release(surf_rt64);
3303 if (surf_rt_dest64)
3304 IDirect3DSurface9_Release(surf_rt_dest64);
3305 if (surf_temp32)
3306 IDirect3DSurface9_Release(surf_temp32);
3307 if (surf_temp64)
3308 IDirect3DSurface9_Release(surf_temp64);
3309 if (surf_offscreen32)
3310 IDirect3DSurface9_Release(surf_offscreen32);
3311 if (surf_offscreen64)
3312 IDirect3DSurface9_Release(surf_offscreen64);
3313 if (surf_offscreen_dest64)
3314 IDirect3DSurface9_Release(surf_offscreen_dest64);
3316 if (tex_rt32) {
3317 if (surf_tex_rt32)
3318 IDirect3DSurface9_Release(surf_tex_rt32);
3319 IDirect3DTexture9_Release(tex_rt32);
3321 if (tex_rt64) {
3322 if (surf_tex_rt64)
3323 IDirect3DSurface9_Release(surf_tex_rt64);
3324 IDirect3DTexture9_Release(tex_rt64);
3326 if (tex_rt_dest64) {
3327 if (surf_tex_rt_dest64)
3328 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3329 IDirect3DTexture9_Release(tex_rt_dest64);
3331 if (tex_rt_dest640_480) {
3332 if (surf_tex_rt_dest640_480)
3333 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3334 IDirect3DTexture9_Release(tex_rt_dest640_480);
3336 if (tex32) {
3337 if (surf_tex32)
3338 IDirect3DSurface9_Release(surf_tex32);
3339 IDirect3DTexture9_Release(tex32);
3341 if (tex64) {
3342 if (surf_tex64)
3343 IDirect3DSurface9_Release(surf_tex64);
3344 IDirect3DTexture9_Release(tex64);
3346 if (tex_dest64) {
3347 if (surf_tex_dest64)
3348 IDirect3DSurface9_Release(surf_tex_dest64);
3349 IDirect3DTexture9_Release(tex_dest64);
3352 if (orig_rt) {
3353 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3354 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3355 IDirect3DSurface9_Release(orig_rt);
3359 static void maxmip_test(IDirect3DDevice9 *device)
3361 IDirect3DTexture9 *texture = NULL;
3362 IDirect3DSurface9 *surface = NULL;
3363 HRESULT hr;
3364 DWORD color;
3365 static const struct
3367 struct
3369 float x, y, z;
3370 float s, t;
3372 v[4];
3374 quads[] =
3377 {-1.0, -1.0, 0.0, 0.0, 0.0},
3378 {-1.0, 0.0, 0.0, 0.0, 1.0},
3379 { 0.0, -1.0, 0.0, 1.0, 0.0},
3380 { 0.0, 0.0, 0.0, 1.0, 1.0},
3383 { 0.0, -1.0, 0.0, 0.0, 0.0},
3384 { 0.0, 0.0, 0.0, 0.0, 1.0},
3385 { 1.0, -1.0, 0.0, 1.0, 0.0},
3386 { 1.0, 0.0, 0.0, 1.0, 1.0},
3389 { 0.0, 0.0, 0.0, 0.0, 0.0},
3390 { 0.0, 1.0, 0.0, 0.0, 1.0},
3391 { 1.0, 0.0, 0.0, 1.0, 0.0},
3392 { 1.0, 1.0, 0.0, 1.0, 1.0},
3395 {-1.0, 0.0, 0.0, 0.0, 0.0},
3396 {-1.0, 1.0, 0.0, 0.0, 1.0},
3397 { 0.0, 0.0, 0.0, 1.0, 0.0},
3398 { 0.0, 1.0, 0.0, 1.0, 1.0},
3402 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3403 &texture, NULL);
3404 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3405 if(!texture)
3407 skip("Failed to create test texture\n");
3408 return;
3411 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3412 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3413 fill_surface(surface, 0xffff0000);
3414 IDirect3DSurface9_Release(surface);
3415 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3416 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3417 fill_surface(surface, 0xff00ff00);
3418 IDirect3DSurface9_Release(surface);
3419 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3420 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3421 fill_surface(surface, 0xff0000ff);
3422 IDirect3DSurface9_Release(surface);
3424 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3425 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3426 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3427 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3429 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3430 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3432 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3433 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3435 hr = IDirect3DDevice9_BeginScene(device);
3436 if(SUCCEEDED(hr))
3438 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3439 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3441 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3443 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3444 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3446 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3448 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3449 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3450 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3451 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3453 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3454 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3456 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3457 hr = IDirect3DDevice9_EndScene(device);
3458 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3461 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3462 color = getPixelColor(device, 160, 360);
3463 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3464 color = getPixelColor(device, 480, 360);
3465 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3466 color = getPixelColor(device, 480, 120);
3467 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3468 color = getPixelColor(device, 160, 120);
3469 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3470 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3471 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3473 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3474 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3477 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3479 hr = IDirect3DDevice9_BeginScene(device);
3480 if(SUCCEEDED(hr))
3482 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3483 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3485 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3487 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3488 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3490 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3492 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3493 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3495 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3497 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3498 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3499 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3500 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3501 hr = IDirect3DDevice9_EndScene(device);
3502 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3505 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3506 * level 3 (> levels in texture) samples from the highest level in the
3507 * texture (level 2). */
3508 color = getPixelColor(device, 160, 360);
3509 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3510 color = getPixelColor(device, 480, 360);
3511 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3512 color = getPixelColor(device, 480, 120);
3513 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3514 color = getPixelColor(device, 160, 120);
3515 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3516 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3517 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3519 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3520 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3522 hr = IDirect3DDevice9_BeginScene(device);
3523 if(SUCCEEDED(hr))
3525 DWORD ret;
3527 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3528 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3530 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3531 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3532 ret = IDirect3DTexture9_SetLOD(texture, 1);
3533 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3535 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3537 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3538 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3539 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3540 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3541 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3542 ret = IDirect3DTexture9_SetLOD(texture, 2);
3543 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3545 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3547 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3548 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3549 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3550 ret = IDirect3DTexture9_SetLOD(texture, 1);
3551 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3553 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3555 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3556 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3557 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3558 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3559 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3560 ret = IDirect3DTexture9_SetLOD(texture, 1);
3561 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3563 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3564 hr = IDirect3DDevice9_EndScene(device);
3565 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3568 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3569 * level 3 (> levels in texture) samples from the highest level in the
3570 * texture (level 2). */
3571 color = getPixelColor(device, 160, 360);
3572 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3573 color = getPixelColor(device, 480, 360);
3574 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3575 color = getPixelColor(device, 480, 120);
3576 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3577 color = getPixelColor(device, 160, 120);
3578 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3580 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3581 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3583 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3584 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3585 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3587 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3588 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3589 IDirect3DTexture9_Release(texture);
3592 static void release_buffer_test(IDirect3DDevice9 *device)
3594 IDirect3DVertexBuffer9 *vb = NULL;
3595 IDirect3DIndexBuffer9 *ib = NULL;
3596 HRESULT hr;
3597 BYTE *data;
3598 LONG ref;
3600 static const struct vertex quad[] = {
3601 {-1.0, -1.0, 0.1, 0xffff0000},
3602 {-1.0, 1.0, 0.1, 0xffff0000},
3603 { 1.0, 1.0, 0.1, 0xffff0000},
3605 {-1.0, -1.0, 0.1, 0xff00ff00},
3606 {-1.0, 1.0, 0.1, 0xff00ff00},
3607 { 1.0, 1.0, 0.1, 0xff00ff00}
3609 short indices[] = {3, 4, 5};
3611 /* Index and vertex buffers should always be creatable */
3612 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3613 D3DPOOL_MANAGED, &vb, NULL);
3614 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3615 if(!vb) {
3616 skip("Failed to create a vertex buffer\n");
3617 return;
3619 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3621 if(!ib) {
3622 skip("Failed to create an index buffer\n");
3623 return;
3626 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3627 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3628 memcpy(data, quad, sizeof(quad));
3629 hr = IDirect3DVertexBuffer9_Unlock(vb);
3630 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3632 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3633 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3634 memcpy(data, indices, sizeof(indices));
3635 hr = IDirect3DIndexBuffer9_Unlock(ib);
3636 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3638 hr = IDirect3DDevice9_SetIndices(device, ib);
3639 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3640 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3641 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3642 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3643 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3645 /* Now destroy the bound index buffer and draw again */
3646 ref = IDirect3DIndexBuffer9_Release(ib);
3647 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3650 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3652 hr = IDirect3DDevice9_BeginScene(device);
3653 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3654 if(SUCCEEDED(hr))
3656 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3657 * making assumptions about the indices or vertices
3659 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3661 hr = IDirect3DDevice9_EndScene(device);
3662 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3665 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3668 hr = IDirect3DDevice9_SetIndices(device, NULL);
3669 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3670 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3671 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3673 /* Index buffer was already destroyed as part of the test */
3674 IDirect3DVertexBuffer9_Release(vb);
3677 static void float_texture_test(IDirect3DDevice9 *device)
3679 IDirect3D9 *d3d = NULL;
3680 HRESULT hr;
3681 IDirect3DTexture9 *texture = NULL;
3682 D3DLOCKED_RECT lr;
3683 float *data;
3684 DWORD color;
3685 float quad[] = {
3686 -1.0, -1.0, 0.1, 0.0, 0.0,
3687 -1.0, 1.0, 0.1, 0.0, 1.0,
3688 1.0, -1.0, 0.1, 1.0, 0.0,
3689 1.0, 1.0, 0.1, 1.0, 1.0,
3692 memset(&lr, 0, sizeof(lr));
3693 IDirect3DDevice9_GetDirect3D(device, &d3d);
3694 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3695 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3696 skip("D3DFMT_R32F textures not supported\n");
3697 goto out;
3700 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3701 D3DPOOL_MANAGED, &texture, NULL);
3702 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3703 if(!texture) {
3704 skip("Failed to create R32F texture\n");
3705 goto out;
3708 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3709 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3710 data = lr.pBits;
3711 *data = 0.0;
3712 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3713 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3715 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3718 hr = IDirect3DDevice9_BeginScene(device);
3719 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3720 if(SUCCEEDED(hr))
3722 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3726 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3728 hr = IDirect3DDevice9_EndScene(device);
3729 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3731 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3732 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3734 color = getPixelColor(device, 240, 320);
3735 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3737 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3738 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3740 out:
3741 if(texture) IDirect3DTexture9_Release(texture);
3742 IDirect3D9_Release(d3d);
3745 static void g16r16_texture_test(IDirect3DDevice9 *device)
3747 IDirect3D9 *d3d = NULL;
3748 HRESULT hr;
3749 IDirect3DTexture9 *texture = NULL;
3750 D3DLOCKED_RECT lr;
3751 DWORD *data;
3752 DWORD color;
3753 float quad[] = {
3754 -1.0, -1.0, 0.1, 0.0, 0.0,
3755 -1.0, 1.0, 0.1, 0.0, 1.0,
3756 1.0, -1.0, 0.1, 1.0, 0.0,
3757 1.0, 1.0, 0.1, 1.0, 1.0,
3760 memset(&lr, 0, sizeof(lr));
3761 IDirect3DDevice9_GetDirect3D(device, &d3d);
3762 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3763 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3764 skip("D3DFMT_G16R16 textures not supported\n");
3765 goto out;
3768 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3769 D3DPOOL_MANAGED, &texture, NULL);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3771 if(!texture) {
3772 skip("Failed to create D3DFMT_G16R16 texture\n");
3773 goto out;
3776 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3777 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3778 data = lr.pBits;
3779 *data = 0x0f00f000;
3780 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3781 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3783 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3784 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3786 hr = IDirect3DDevice9_BeginScene(device);
3787 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3788 if(SUCCEEDED(hr))
3790 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3791 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3794 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3796 hr = IDirect3DDevice9_EndScene(device);
3797 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3799 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3802 color = getPixelColor(device, 240, 320);
3803 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3804 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3806 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3807 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3809 out:
3810 if(texture) IDirect3DTexture9_Release(texture);
3811 IDirect3D9_Release(d3d);
3814 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3816 LONG x_coords[2][2] =
3818 {r.left - 1, r.left + 1},
3819 {r.right + 1, r.right - 1},
3821 LONG y_coords[2][2] =
3823 {r.top - 1, r.top + 1},
3824 {r.bottom + 1, r.bottom - 1}
3826 unsigned int i, j, x_side, y_side;
3828 for (i = 0; i < 2; ++i)
3830 for (j = 0; j < 2; ++j)
3832 for (x_side = 0; x_side < 2; ++x_side)
3834 for (y_side = 0; y_side < 2; ++y_side)
3836 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3837 DWORD color;
3838 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3840 color = getPixelColor(device, x, y);
3841 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3842 message, x, y, color, expected);
3849 struct projected_textures_test_run
3851 const char *message;
3852 DWORD flags;
3853 IDirect3DVertexDeclaration9 *decl;
3854 BOOL vs, ps;
3855 RECT rect;
3858 static void projected_textures_test(IDirect3DDevice9 *device,
3859 struct projected_textures_test_run tests[4])
3861 unsigned int i;
3863 static const DWORD vertex_shader[] =
3865 0xfffe0101, /* vs_1_1 */
3866 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3867 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
3868 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3869 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
3870 0x0000ffff /* end */
3872 static const DWORD pixel_shader[] =
3874 0xffff0103, /* ps_1_3 */
3875 0x00000042, 0xb00f0000, /* tex t0 */
3876 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3877 0x0000ffff /* end */
3879 IDirect3DVertexShader9 *vs = NULL;
3880 IDirect3DPixelShader9 *ps = NULL;
3881 HRESULT hr;
3883 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3884 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3885 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3886 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3889 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3891 hr = IDirect3DDevice9_BeginScene(device);
3892 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3893 if (FAILED(hr))
3894 return;
3896 for (i = 0; i < 4; ++i)
3898 DWORD value = 0xdeadbeef;
3899 static const float proj_quads[] =
3901 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3902 0.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3903 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3904 0.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3906 0.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3907 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3908 0.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3909 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3911 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3912 0.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3913 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3914 0.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3916 0.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3917 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3918 0.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3919 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3922 if (tests[i].vs)
3923 hr = IDirect3DDevice9_SetVertexShader(device, vs);
3924 else
3925 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3926 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3927 if (tests[i].ps)
3928 hr = IDirect3DDevice9_SetPixelShader(device, ps);
3929 else
3930 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3931 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3933 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3934 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3936 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3937 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3938 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3939 ok(SUCCEEDED(hr) && value == tests[i].flags,
3940 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3943 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3944 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3947 hr = IDirect3DDevice9_EndScene(device);
3948 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3950 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3951 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3952 IDirect3DVertexShader9_Release(vs);
3953 IDirect3DPixelShader9_Release(ps);
3955 for (i = 0; i < 4; ++i)
3956 check_rect(device, tests[i].rect, tests[i].message);
3958 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3959 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3962 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3964 HRESULT hr;
3965 IDirect3D9 *d3d;
3966 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3967 D3DCAPS9 caps;
3968 IDirect3DTexture9 *texture = NULL;
3969 IDirect3DVolumeTexture9 *volume = NULL;
3970 unsigned int x, y, z;
3971 D3DLOCKED_RECT lr;
3972 D3DLOCKED_BOX lb;
3973 DWORD color;
3974 UINT w, h;
3975 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3976 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3977 0.0, 1.0, 0.0, 0.0,
3978 0.0, 0.0, 1.0, 0.0,
3979 0.0, 0.0, 0.0, 1.0};
3980 static const D3DVERTEXELEMENT9 decl_elements[] = {
3981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3982 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3983 D3DDECL_END()
3985 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3987 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3988 D3DDECL_END()
3990 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3991 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3992 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3993 D3DDECL_END()
3995 static const D3DVERTEXELEMENT9 decl_elements4[] = {
3996 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3997 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3998 D3DDECL_END()
4000 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4001 0x00, 0xff, 0x00, 0x00,
4002 0x00, 0x00, 0x00, 0x00,
4003 0x00, 0x00, 0x00, 0x00};
4005 memset(&lr, 0, sizeof(lr));
4006 memset(&lb, 0, sizeof(lb));
4007 IDirect3DDevice9_GetDirect3D(device, &d3d);
4008 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4009 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4010 fmt = D3DFMT_A16B16G16R16;
4012 IDirect3D9_Release(d3d);
4014 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4015 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4016 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4017 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4018 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4019 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4020 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4022 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4023 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4024 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4025 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4026 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4027 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4028 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4029 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4030 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4031 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4032 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4033 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4034 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4035 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4036 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4038 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4041 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4042 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4043 w = min(1024, caps.MaxTextureWidth);
4044 h = min(1024, caps.MaxTextureHeight);
4045 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4046 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4047 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4048 if(!texture) {
4049 skip("Failed to create the test texture\n");
4050 return;
4053 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4054 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4055 * 1.0 in red and green for the x and y coords
4057 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4058 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4059 for(y = 0; y < h; y++) {
4060 for(x = 0; x < w; x++) {
4061 double r_f = (double) y / (double) h;
4062 double g_f = (double) x / (double) w;
4063 if(fmt == D3DFMT_A16B16G16R16) {
4064 unsigned short r, g;
4065 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4066 r = (unsigned short) (r_f * 65536.0);
4067 g = (unsigned short) (g_f * 65536.0);
4068 dst[0] = r;
4069 dst[1] = g;
4070 dst[2] = 0;
4071 dst[3] = 65535;
4072 } else {
4073 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4074 unsigned char r = (unsigned char) (r_f * 255.0);
4075 unsigned char g = (unsigned char) (g_f * 255.0);
4076 dst[0] = 0;
4077 dst[1] = g;
4078 dst[2] = r;
4079 dst[3] = 255;
4083 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4084 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4085 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4086 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4088 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4089 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4090 hr = IDirect3DDevice9_BeginScene(device);
4091 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4092 if(SUCCEEDED(hr))
4094 float quad1[] = {
4095 -1.0, -1.0, 0.1, 1.0, 1.0,
4096 -1.0, 0.0, 0.1, 1.0, 1.0,
4097 0.0, -1.0, 0.1, 1.0, 1.0,
4098 0.0, 0.0, 0.1, 1.0, 1.0,
4100 float quad2[] = {
4101 -1.0, 0.0, 0.1, 1.0, 1.0,
4102 -1.0, 1.0, 0.1, 1.0, 1.0,
4103 0.0, 0.0, 0.1, 1.0, 1.0,
4104 0.0, 1.0, 0.1, 1.0, 1.0,
4106 float quad3[] = {
4107 0.0, 0.0, 0.1, 0.5, 0.5,
4108 0.0, 1.0, 0.1, 0.5, 0.5,
4109 1.0, 0.0, 0.1, 0.5, 0.5,
4110 1.0, 1.0, 0.1, 0.5, 0.5,
4112 float quad4[] = {
4113 320, 480, 0.1, 1.0, 0.0, 1.0,
4114 320, 240, 0.1, 1.0, 0.0, 1.0,
4115 640, 480, 0.1, 1.0, 0.0, 1.0,
4116 640, 240, 0.1, 1.0, 0.0, 1.0,
4118 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4119 0.0, 0.0, 0.0, 0.0,
4120 0.0, 0.0, 0.0, 0.0,
4121 0.0, 0.0, 0.0, 0.0};
4123 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4124 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4125 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4126 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4127 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4129 /* What happens with transforms enabled? */
4130 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4131 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4135 /* What happens if 4 coords are used, but only 2 given ?*/
4136 mat[8] = 1.0;
4137 mat[13] = 1.0;
4138 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4139 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4141 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4143 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4145 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4146 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4147 * due to the coords in the vertices. (turns out red, indeed)
4149 memset(mat, 0, sizeof(mat));
4150 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4151 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4152 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4153 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4154 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4155 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4157 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4159 hr = IDirect3DDevice9_EndScene(device);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4162 color = getPixelColor(device, 160, 360);
4163 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4164 color = getPixelColor(device, 160, 120);
4165 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4166 color = getPixelColor(device, 480, 120);
4167 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4168 color = getPixelColor(device, 480, 360);
4169 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4170 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4173 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4174 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4176 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4177 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4178 hr = IDirect3DDevice9_BeginScene(device);
4179 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4180 if(SUCCEEDED(hr))
4182 float quad1[] = {
4183 -1.0, -1.0, 0.1, 0.8, 0.2,
4184 -1.0, 0.0, 0.1, 0.8, 0.2,
4185 0.0, -1.0, 0.1, 0.8, 0.2,
4186 0.0, 0.0, 0.1, 0.8, 0.2,
4188 float quad2[] = {
4189 -1.0, 0.0, 0.1, 0.5, 1.0,
4190 -1.0, 1.0, 0.1, 0.5, 1.0,
4191 0.0, 0.0, 0.1, 0.5, 1.0,
4192 0.0, 1.0, 0.1, 0.5, 1.0,
4194 float quad3[] = {
4195 0.0, 0.0, 0.1, 0.5, 1.0,
4196 0.0, 1.0, 0.1, 0.5, 1.0,
4197 1.0, 0.0, 0.1, 0.5, 1.0,
4198 1.0, 1.0, 0.1, 0.5, 1.0,
4200 float quad4[] = {
4201 0.0, -1.0, 0.1, 0.8, 0.2,
4202 0.0, 0.0, 0.1, 0.8, 0.2,
4203 1.0, -1.0, 0.1, 0.8, 0.2,
4204 1.0, 0.0, 0.1, 0.8, 0.2,
4206 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4207 0.0, 0.0, 0.0, 0.0,
4208 0.0, 1.0, 0.0, 0.0,
4209 0.0, 0.0, 0.0, 0.0};
4211 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4212 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4213 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4214 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4218 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4220 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4221 * it behaves like COUNT2 because normal textures require 2 coords. */
4222 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4223 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4225 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4227 /* Just to be sure, the same as quad2 above */
4228 memset(mat, 0, sizeof(mat));
4229 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4230 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4231 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4232 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4234 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4236 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4237 * used? And what happens to the first? */
4238 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4241 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4243 hr = IDirect3DDevice9_EndScene(device);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4246 color = getPixelColor(device, 160, 360);
4247 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4248 color = getPixelColor(device, 160, 120);
4249 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4250 color = getPixelColor(device, 480, 120);
4251 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4252 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4253 color = getPixelColor(device, 480, 360);
4254 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4255 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4257 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4259 IDirect3DTexture9_Release(texture);
4261 /* Test projected textures, without any fancy matrices */
4262 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4264 if (SUCCEEDED(hr))
4266 struct projected_textures_test_run projected_tests_1[4] =
4269 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4270 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4271 decl3,
4272 FALSE, TRUE,
4273 {120, 300, 240, 390},
4276 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4277 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4278 decl3,
4279 FALSE, TRUE,
4280 {400, 360, 480, 420},
4282 /* Try with some invalid values */
4284 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4285 0xffffffff,
4286 decl3,
4287 FALSE, TRUE,
4288 {120, 60, 240, 150}
4291 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4292 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4293 decl4,
4294 FALSE, TRUE,
4295 {340, 210, 360, 225},
4298 struct projected_textures_test_run projected_tests_2[4] =
4301 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4302 D3DTTFF_PROJECTED,
4303 decl3,
4304 FALSE, TRUE,
4305 {120, 300, 240, 390},
4308 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4309 D3DTTFF_PROJECTED,
4310 decl,
4311 FALSE, TRUE,
4312 {400, 360, 480, 420},
4315 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4316 0xffffffff,
4317 decl,
4318 FALSE, TRUE,
4319 {80, 120, 160, 180},
4322 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4323 D3DTTFF_COUNT1,
4324 decl4,
4325 FALSE, TRUE,
4326 {340, 210, 360, 225},
4329 struct projected_textures_test_run projected_tests_3[4] =
4332 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4333 D3DTTFF_PROJECTED,
4334 decl3,
4335 TRUE, FALSE,
4336 {120, 300, 240, 390},
4339 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4340 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4341 decl3,
4342 TRUE, TRUE,
4343 {440, 300, 560, 390},
4346 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4347 0xffffffff,
4348 decl3,
4349 TRUE, TRUE,
4350 {120, 60, 240, 150},
4353 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4354 D3DTTFF_PROJECTED,
4355 decl3,
4356 FALSE, FALSE,
4357 {440, 60, 560, 150},
4361 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4362 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4364 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4365 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4366 for(x = 0; x < 4; x++) {
4367 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4369 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4370 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4371 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4372 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4374 projected_textures_test(device, projected_tests_1);
4375 projected_textures_test(device, projected_tests_2);
4376 projected_textures_test(device, projected_tests_3);
4378 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4379 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4380 IDirect3DTexture9_Release(texture);
4383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4384 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4385 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4386 * Thus watch out if sampling from texels between 0 and 1.
4388 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4389 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4390 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4391 if(!volume) {
4392 skip("Failed to create a volume texture\n");
4393 goto out;
4396 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4397 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4398 for(z = 0; z < 32; z++) {
4399 for(y = 0; y < 32; y++) {
4400 for(x = 0; x < 32; x++) {
4401 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4402 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4403 float r_f = (float) x / 31.0;
4404 float g_f = (float) y / 31.0;
4405 float b_f = (float) z / 31.0;
4407 if(fmt == D3DFMT_A16B16G16R16) {
4408 unsigned short *mem_s = mem;
4409 mem_s[0] = r_f * 65535.0;
4410 mem_s[1] = g_f * 65535.0;
4411 mem_s[2] = b_f * 65535.0;
4412 mem_s[3] = 65535;
4413 } else {
4414 unsigned char *mem_c = mem;
4415 mem_c[0] = b_f * 255.0;
4416 mem_c[1] = g_f * 255.0;
4417 mem_c[2] = r_f * 255.0;
4418 mem_c[3] = 255;
4423 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4424 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4426 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4427 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4429 hr = IDirect3DDevice9_BeginScene(device);
4430 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4431 if(SUCCEEDED(hr))
4433 float quad1[] = {
4434 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4435 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4436 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4437 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4439 float quad2[] = {
4440 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4441 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4442 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4443 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4445 float quad3[] = {
4446 0.0, 0.0, 0.1, 0.0, 0.0,
4447 0.0, 1.0, 0.1, 0.0, 0.0,
4448 1.0, 0.0, 0.1, 0.0, 0.0,
4449 1.0, 1.0, 0.1, 0.0, 0.0
4451 float quad4[] = {
4452 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4453 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4454 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4455 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4457 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4458 0.0, 0.0, 1.0, 0.0,
4459 0.0, 1.0, 0.0, 0.0,
4460 0.0, 0.0, 0.0, 1.0};
4461 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4462 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4464 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4465 * values
4467 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4468 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4469 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4470 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4472 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4474 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4475 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4476 * otherwise the w will be missing(blue).
4477 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4478 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4479 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4480 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4482 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4484 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4485 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4486 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4487 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4488 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4490 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4492 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4494 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4495 * disable. ATI extends it up to the amount of values needed for the volume texture
4497 memset(mat, 0, sizeof(mat));
4498 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4499 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4500 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4501 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4502 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4503 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4505 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4507 hr = IDirect3DDevice9_EndScene(device);
4508 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4511 color = getPixelColor(device, 160, 360);
4512 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4513 color = getPixelColor(device, 160, 120);
4514 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4515 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4516 color = getPixelColor(device, 480, 120);
4517 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4518 color = getPixelColor(device, 480, 360);
4519 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4521 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4522 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4525 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4526 hr = IDirect3DDevice9_BeginScene(device);
4527 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4528 if(SUCCEEDED(hr))
4530 float quad1[] = {
4531 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4532 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4533 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4534 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4536 float quad2[] = {
4537 -1.0, 0.0, 0.1,
4538 -1.0, 1.0, 0.1,
4539 0.0, 0.0, 0.1,
4540 0.0, 1.0, 0.1,
4542 float quad3[] = {
4543 0.0, 0.0, 0.1, 1.0,
4544 0.0, 1.0, 0.1, 1.0,
4545 1.0, 0.0, 0.1, 1.0,
4546 1.0, 1.0, 0.1, 1.0
4548 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4549 0.0, 0.0, 0.0, 0.0,
4550 0.0, 0.0, 0.0, 0.0,
4551 0.0, 1.0, 0.0, 0.0};
4552 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4553 1.0, 0.0, 0.0, 0.0,
4554 0.0, 1.0, 0.0, 0.0,
4555 0.0, 0.0, 1.0, 0.0};
4556 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4559 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4560 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4561 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4562 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4563 * 4th *input* coordinate.
4565 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4566 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4567 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4568 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4569 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4570 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4572 /* None passed */
4573 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4574 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4576 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4578 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4580 /* 4 used, 1 passed */
4581 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4582 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4583 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4586 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4588 hr = IDirect3DDevice9_EndScene(device);
4589 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4591 color = getPixelColor(device, 160, 360);
4592 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4593 color = getPixelColor(device, 160, 120);
4594 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4595 color = getPixelColor(device, 480, 120);
4596 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4597 /* Quad4: unused */
4599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4600 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4602 IDirect3DVolumeTexture9_Release(volume);
4604 out:
4605 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4606 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4607 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4608 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4609 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4610 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4611 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4612 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4613 IDirect3DVertexDeclaration9_Release(decl);
4614 IDirect3DVertexDeclaration9_Release(decl2);
4615 IDirect3DVertexDeclaration9_Release(decl3);
4616 IDirect3DVertexDeclaration9_Release(decl4);
4619 static void texdepth_test(IDirect3DDevice9 *device)
4621 IDirect3DPixelShader9 *shader;
4622 HRESULT hr;
4623 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4624 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4625 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4626 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4627 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4628 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4629 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4630 DWORD shader_code[] = {
4631 0xffff0104, /* ps_1_4 */
4632 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4633 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4634 0x0000fffd, /* phase */
4635 0x00000057, 0x800f0005, /* texdepth r5 */
4636 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4637 0x0000ffff /* end */
4639 DWORD color;
4640 float vertex[] = {
4641 -1.0, -1.0, 0.0,
4642 1.0, -1.0, 1.0,
4643 -1.0, 1.0, 0.0,
4644 1.0, 1.0, 1.0
4647 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4648 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4651 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4653 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4655 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4657 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4658 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4659 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4661 /* Fill the depth buffer with a gradient */
4662 hr = IDirect3DDevice9_BeginScene(device);
4663 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4664 if(SUCCEEDED(hr))
4666 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4667 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);
4672 /* Now perform the actual tests. Same geometry, but with the shader */
4673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4675 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4676 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4677 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4678 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4680 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4681 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4682 hr = IDirect3DDevice9_BeginScene(device);
4683 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4684 if(SUCCEEDED(hr))
4686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4687 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4689 hr = IDirect3DDevice9_EndScene(device);
4690 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4693 color = getPixelColor(device, 158, 240);
4694 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4695 color = getPixelColor(device, 162, 240);
4696 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\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, 0xffffff00, 0.0, 0);
4702 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4704 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 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, 318, 240);
4718 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4719 color = getPixelColor(device, 322, 240);
4720 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4722 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4723 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4725 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4726 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4728 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4729 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4730 hr = IDirect3DDevice9_BeginScene(device);
4731 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4732 if(SUCCEEDED(hr))
4734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4735 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4737 hr = IDirect3DDevice9_EndScene(device);
4738 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4741 color = getPixelColor(device, 1, 240);
4742 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4744 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4748 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4750 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4752 hr = IDirect3DDevice9_BeginScene(device);
4753 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4754 if(SUCCEEDED(hr))
4756 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4757 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4759 hr = IDirect3DDevice9_EndScene(device);
4760 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4762 color = getPixelColor(device, 318, 240);
4763 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4764 color = getPixelColor(device, 322, 240);
4765 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4767 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4768 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4771 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4773 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4774 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4775 hr = IDirect3DDevice9_BeginScene(device);
4776 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4777 if(SUCCEEDED(hr))
4779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4780 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4782 hr = IDirect3DDevice9_EndScene(device);
4783 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4786 color = getPixelColor(device, 1, 240);
4787 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4789 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4790 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4792 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4793 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4795 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4797 hr = IDirect3DDevice9_BeginScene(device);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4799 if(SUCCEEDED(hr))
4801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4804 hr = IDirect3DDevice9_EndScene(device);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4808 color = getPixelColor(device, 638, 240);
4809 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4812 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4814 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4815 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4817 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4818 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4819 hr = IDirect3DDevice9_BeginScene(device);
4820 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4821 if(SUCCEEDED(hr))
4823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4824 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4826 hr = IDirect3DDevice9_EndScene(device);
4827 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4830 color = getPixelColor(device, 638, 240);
4831 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4836 /* Cleanup */
4837 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4839 IDirect3DPixelShader9_Release(shader);
4841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4847 static void texkill_test(IDirect3DDevice9 *device)
4849 IDirect3DPixelShader9 *shader;
4850 HRESULT hr;
4851 DWORD color;
4853 const float vertex[] = {
4854 /* bottom top right left */
4855 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4856 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4857 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4858 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4861 DWORD shader_code_11[] = {
4862 0xffff0101, /* ps_1_1 */
4863 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4864 0x00000041, 0xb00f0000, /* texkill t0 */
4865 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4866 0x0000ffff /* end */
4868 DWORD shader_code_20[] = {
4869 0xffff0200, /* ps_2_0 */
4870 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4871 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4872 0x01000041, 0xb00f0000, /* texkill t0 */
4873 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4874 0x0000ffff /* end */
4877 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4878 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4879 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4880 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4882 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884 hr = IDirect3DDevice9_BeginScene(device);
4885 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4886 if(SUCCEEDED(hr))
4888 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4889 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4891 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4892 hr = IDirect3DDevice9_EndScene(device);
4893 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4895 color = getPixelColor(device, 63, 46);
4896 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4897 color = getPixelColor(device, 66, 46);
4898 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4899 color = getPixelColor(device, 63, 49);
4900 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4901 color = getPixelColor(device, 66, 49);
4902 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4904 color = getPixelColor(device, 578, 46);
4905 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4906 color = getPixelColor(device, 575, 46);
4907 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4908 color = getPixelColor(device, 578, 49);
4909 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4910 color = getPixelColor(device, 575, 49);
4911 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4913 color = getPixelColor(device, 63, 430);
4914 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4915 color = getPixelColor(device, 63, 433);
4916 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4917 color = getPixelColor(device, 66, 433);
4918 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4919 color = getPixelColor(device, 66, 430);
4920 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4922 color = getPixelColor(device, 578, 430);
4923 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4924 color = getPixelColor(device, 578, 433);
4925 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4926 color = getPixelColor(device, 575, 433);
4927 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4928 color = getPixelColor(device, 575, 430);
4929 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4931 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4932 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4934 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4935 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4936 IDirect3DPixelShader9_Release(shader);
4938 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4939 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4941 if(FAILED(hr)) {
4942 skip("Failed to create 2.0 test shader, most likely not supported\n");
4943 return;
4946 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4947 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4948 hr = IDirect3DDevice9_BeginScene(device);
4949 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4950 if(SUCCEEDED(hr))
4952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4953 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4954 hr = IDirect3DDevice9_EndScene(device);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4958 color = getPixelColor(device, 63, 46);
4959 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4960 color = getPixelColor(device, 66, 46);
4961 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4962 color = getPixelColor(device, 63, 49);
4963 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4964 color = getPixelColor(device, 66, 49);
4965 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4967 color = getPixelColor(device, 578, 46);
4968 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4969 color = getPixelColor(device, 575, 46);
4970 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4971 color = getPixelColor(device, 578, 49);
4972 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4973 color = getPixelColor(device, 575, 49);
4974 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4976 color = getPixelColor(device, 63, 430);
4977 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4978 color = getPixelColor(device, 63, 433);
4979 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4980 color = getPixelColor(device, 66, 433);
4981 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4982 color = getPixelColor(device, 66, 430);
4983 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4985 color = getPixelColor(device, 578, 430);
4986 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4987 color = getPixelColor(device, 578, 433);
4988 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4989 color = getPixelColor(device, 575, 433);
4990 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4991 color = getPixelColor(device, 575, 430);
4992 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4994 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4995 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4997 /* Cleanup */
4998 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5000 IDirect3DPixelShader9_Release(shader);
5003 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5005 IDirect3D9 *d3d9;
5006 HRESULT hr;
5007 IDirect3DTexture9 *texture;
5008 IDirect3DPixelShader9 *shader;
5009 IDirect3DPixelShader9 *shader2;
5010 D3DLOCKED_RECT lr;
5011 DWORD color;
5012 DWORD shader_code[] = {
5013 0xffff0101, /* ps_1_1 */
5014 0x00000042, 0xb00f0000, /* tex t0 */
5015 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5016 0x0000ffff /* end */
5018 DWORD shader_code2[] = {
5019 0xffff0101, /* ps_1_1 */
5020 0x00000042, 0xb00f0000, /* tex t0 */
5021 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
5022 0x0000ffff /* end */
5025 float quad[] = {
5026 -1.0, -1.0, 0.1, 0.5, 0.5,
5027 1.0, -1.0, 0.1, 0.5, 0.5,
5028 -1.0, 1.0, 0.1, 0.5, 0.5,
5029 1.0, 1.0, 0.1, 0.5, 0.5,
5032 memset(&lr, 0, sizeof(lr));
5033 IDirect3DDevice9_GetDirect3D(device, &d3d9);
5034 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5035 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5036 IDirect3D9_Release(d3d9);
5037 if(FAILED(hr)) {
5038 skip("No D3DFMT_X8L8V8U8 support\n");
5039 return;
5042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5043 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5045 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5046 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5047 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5048 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5049 *((DWORD *) lr.pBits) = 0x11ca3141;
5050 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5051 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5053 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5054 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5055 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5056 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5059 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5060 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5061 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5062 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5065 hr = IDirect3DDevice9_BeginScene(device);
5066 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5067 if(SUCCEEDED(hr))
5069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5070 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5072 hr = IDirect3DDevice9_EndScene(device);
5073 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5075 color = getPixelColor(device, 578, 430);
5076 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5077 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5078 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5081 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5082 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5083 hr = IDirect3DDevice9_BeginScene(device);
5084 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5085 if(SUCCEEDED(hr))
5087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5088 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5090 hr = IDirect3DDevice9_EndScene(device);
5091 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5093 color = getPixelColor(device, 578, 430);
5094 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5095 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5098 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5099 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5100 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5101 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5102 IDirect3DPixelShader9_Release(shader);
5103 IDirect3DPixelShader9_Release(shader2);
5104 IDirect3DTexture9_Release(texture);
5107 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5109 HRESULT hr;
5110 IDirect3D9 *d3d;
5111 IDirect3DTexture9 *texture = NULL;
5112 IDirect3DSurface9 *surface;
5113 DWORD color;
5114 const RECT r1 = {256, 256, 512, 512};
5115 const RECT r2 = {512, 256, 768, 512};
5116 const RECT r3 = {256, 512, 512, 768};
5117 const RECT r4 = {512, 512, 768, 768};
5118 unsigned int x, y;
5119 D3DLOCKED_RECT lr;
5120 memset(&lr, 0, sizeof(lr));
5122 IDirect3DDevice9_GetDirect3D(device, &d3d);
5123 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5124 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5125 skip("No autogenmipmap support\n");
5126 IDirect3D9_Release(d3d);
5127 return;
5129 IDirect3D9_Release(d3d);
5131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5132 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5134 /* Make the mipmap big, so that a smaller mipmap is used
5136 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5137 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5138 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5140 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5141 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5142 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5143 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5144 for(y = 0; y < 1024; y++) {
5145 for(x = 0; x < 1024; x++) {
5146 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5147 POINT pt;
5149 pt.x = x;
5150 pt.y = y;
5151 if(PtInRect(&r1, pt)) {
5152 *dst = 0xffff0000;
5153 } else if(PtInRect(&r2, pt)) {
5154 *dst = 0xff00ff00;
5155 } else if(PtInRect(&r3, pt)) {
5156 *dst = 0xff0000ff;
5157 } else if(PtInRect(&r4, pt)) {
5158 *dst = 0xff000000;
5159 } else {
5160 *dst = 0xffffffff;
5164 hr = IDirect3DSurface9_UnlockRect(surface);
5165 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5166 IDirect3DSurface9_Release(surface);
5168 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5169 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5171 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5173 hr = IDirect3DDevice9_BeginScene(device);
5174 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5175 if(SUCCEEDED(hr)) {
5176 const float quad[] = {
5177 -0.5, -0.5, 0.1, 0.0, 0.0,
5178 -0.5, 0.5, 0.1, 0.0, 1.0,
5179 0.5, -0.5, 0.1, 1.0, 0.0,
5180 0.5, 0.5, 0.1, 1.0, 1.0
5183 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5184 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5185 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5186 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5187 hr = IDirect3DDevice9_EndScene(device);
5188 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5190 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5191 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5192 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5194 IDirect3DTexture9_Release(texture);
5196 color = getPixelColor(device, 200, 200);
5197 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5198 color = getPixelColor(device, 280, 200);
5199 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5200 color = getPixelColor(device, 360, 200);
5201 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5202 color = getPixelColor(device, 440, 200);
5203 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5204 color = getPixelColor(device, 200, 270);
5205 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5206 color = getPixelColor(device, 280, 270);
5207 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5208 color = getPixelColor(device, 360, 270);
5209 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5210 color = getPixelColor(device, 440, 270);
5211 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5212 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5213 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5216 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5218 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5219 IDirect3DVertexDeclaration9 *decl;
5220 HRESULT hr;
5221 DWORD color;
5222 DWORD shader_code_11[] = {
5223 0xfffe0101, /* vs_1_1 */
5224 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5225 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5226 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5227 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5228 0x0000ffff /* end */
5230 DWORD shader_code_11_2[] = {
5231 0xfffe0101, /* vs_1_1 */
5232 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5233 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5234 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5235 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5236 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5237 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5238 0x0000ffff /* end */
5240 DWORD shader_code_20[] = {
5241 0xfffe0200, /* vs_2_0 */
5242 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5243 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5244 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5245 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5246 0x0000ffff /* end */
5248 DWORD shader_code_20_2[] = {
5249 0xfffe0200, /* vs_2_0 */
5250 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5251 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5252 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5253 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5254 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5255 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5256 0x0000ffff /* end */
5258 static const D3DVERTEXELEMENT9 decl_elements[] = {
5259 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5260 D3DDECL_END()
5262 float quad1[] = {
5263 -1.0, -1.0, 0.1,
5264 0.0, -1.0, 0.1,
5265 -1.0, 0.0, 0.1,
5266 0.0, 0.0, 0.1
5268 float quad2[] = {
5269 0.0, -1.0, 0.1,
5270 1.0, -1.0, 0.1,
5271 0.0, 0.0, 0.1,
5272 1.0, 0.0, 0.1
5274 float quad3[] = {
5275 0.0, 0.0, 0.1,
5276 1.0, 0.0, 0.1,
5277 0.0, 1.0, 0.1,
5278 1.0, 1.0, 0.1
5280 float quad4[] = {
5281 -1.0, 0.0, 0.1,
5282 0.0, 0.0, 0.1,
5283 -1.0, 1.0, 0.1,
5284 0.0, 1.0, 0.1
5286 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5287 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5289 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5290 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5292 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5293 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5294 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5296 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5297 if(FAILED(hr)) shader_20 = NULL;
5298 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5299 if(FAILED(hr)) shader_20_2 = NULL;
5300 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5301 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5303 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5305 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5307 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5310 hr = IDirect3DDevice9_BeginScene(device);
5311 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5312 if(SUCCEEDED(hr))
5314 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5315 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5317 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5319 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5324 if(shader_20) {
5325 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5326 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5328 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5331 if(shader_20_2) {
5332 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5333 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5335 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5338 hr = IDirect3DDevice9_EndScene(device);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5342 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5344 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5345 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5347 color = getPixelColor(device, 160, 360);
5348 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5349 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5350 color = getPixelColor(device, 480, 360);
5351 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5352 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5353 if(shader_20) {
5354 color = getPixelColor(device, 480, 120);
5355 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5356 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5358 if(shader_20_2) {
5359 color = getPixelColor(device, 160, 120);
5360 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5361 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5363 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5364 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5366 IDirect3DVertexDeclaration9_Release(decl);
5367 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5368 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5369 IDirect3DVertexShader9_Release(shader_11_2);
5370 IDirect3DVertexShader9_Release(shader_11);
5373 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5375 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5376 HRESULT hr;
5377 DWORD color;
5378 DWORD shader_code_11[] = {
5379 0xffff0101, /* ps_1_1 */
5380 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5381 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5382 0x0000ffff /* end */
5384 DWORD shader_code_12[] = {
5385 0xffff0102, /* ps_1_2 */
5386 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5387 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5388 0x0000ffff /* end */
5390 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5391 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5392 * During development of this test, 1.3 shaders were verified too
5394 DWORD shader_code_14[] = {
5395 0xffff0104, /* ps_1_4 */
5396 /* Try to make one constant local. It gets clamped too, although the binary contains
5397 * the bigger numbers
5399 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5400 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5401 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5402 0x0000ffff /* end */
5404 DWORD shader_code_20[] = {
5405 0xffff0200, /* ps_2_0 */
5406 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5407 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5408 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5409 0x0000ffff /* end */
5411 float quad1[] = {
5412 -1.0, -1.0, 0.1,
5413 0.0, -1.0, 0.1,
5414 -1.0, 0.0, 0.1,
5415 0.0, 0.0, 0.1
5417 float quad2[] = {
5418 0.0, -1.0, 0.1,
5419 1.0, -1.0, 0.1,
5420 0.0, 0.0, 0.1,
5421 1.0, 0.0, 0.1
5423 float quad3[] = {
5424 0.0, 0.0, 0.1,
5425 1.0, 0.0, 0.1,
5426 0.0, 1.0, 0.1,
5427 1.0, 1.0, 0.1
5429 float quad4[] = {
5430 -1.0, 0.0, 0.1,
5431 0.0, 0.0, 0.1,
5432 -1.0, 1.0, 0.1,
5433 0.0, 1.0, 0.1
5435 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
5436 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
5438 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5439 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5441 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5442 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5443 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5444 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5445 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5446 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5447 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5448 if(FAILED(hr)) shader_20 = NULL;
5450 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5451 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5452 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5453 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5454 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5457 hr = IDirect3DDevice9_BeginScene(device);
5458 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5459 if(SUCCEEDED(hr))
5461 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5462 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5464 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5466 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5467 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5469 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5471 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5472 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5474 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5476 if(shader_20) {
5477 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5478 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5480 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5483 hr = IDirect3DDevice9_EndScene(device);
5484 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5486 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5487 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5489 color = getPixelColor(device, 160, 360);
5490 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5491 "quad 1 has color %08x, expected 0x00808000\n", color);
5492 color = getPixelColor(device, 480, 360);
5493 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5494 "quad 2 has color %08x, expected 0x00808000\n", color);
5495 color = getPixelColor(device, 480, 120);
5496 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5497 "quad 3 has color %08x, expected 0x00808000\n", color);
5498 if(shader_20) {
5499 color = getPixelColor(device, 160, 120);
5500 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5501 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5503 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5504 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5506 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5507 IDirect3DPixelShader9_Release(shader_14);
5508 IDirect3DPixelShader9_Release(shader_12);
5509 IDirect3DPixelShader9_Release(shader_11);
5512 static void dp2add_ps_test(IDirect3DDevice9 *device)
5514 IDirect3DPixelShader9 *shader_dp2add = NULL;
5515 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5516 HRESULT hr;
5517 DWORD color;
5519 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5520 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5521 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5522 * r0 first.
5523 * The result here for the r,g,b components should be roughly 0.5:
5524 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5525 static const DWORD shader_code_dp2add[] = {
5526 0xffff0200, /* ps_2_0 */
5527 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5529 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5530 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5532 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5533 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5534 0x0000ffff /* end */
5537 /* Test the _sat modifier, too. Result here should be:
5538 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5539 * _SAT: ==> 1.0
5540 * ADD: (1.0 + -0.5) = 0.5
5542 static const DWORD shader_code_dp2add_sat[] = {
5543 0xffff0200, /* ps_2_0 */
5544 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5546 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5547 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5548 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5550 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5551 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5552 0x0000ffff /* end */
5555 const float quad[] = {
5556 -1.0, -1.0, 0.1,
5557 1.0, -1.0, 0.1,
5558 -1.0, 1.0, 0.1,
5559 1.0, 1.0, 0.1
5563 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5564 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5566 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5567 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5569 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5570 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5575 if (shader_dp2add) {
5577 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5578 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5580 hr = IDirect3DDevice9_BeginScene(device);
5581 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5582 if(SUCCEEDED(hr))
5584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5585 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5587 hr = IDirect3DDevice9_EndScene(device);
5588 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5591 color = getPixelColor(device, 360, 240);
5592 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5593 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5596 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5598 IDirect3DPixelShader9_Release(shader_dp2add);
5599 } else {
5600 skip("dp2add shader creation failed\n");
5603 if (shader_dp2add_sat) {
5605 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5606 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5608 hr = IDirect3DDevice9_BeginScene(device);
5609 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5610 if(SUCCEEDED(hr))
5612 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5613 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5615 hr = IDirect3DDevice9_EndScene(device);
5616 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5619 color = getPixelColor(device, 360, 240);
5620 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5621 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5626 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5627 } else {
5628 skip("dp2add shader creation failed\n");
5631 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5632 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5635 static void cnd_test(IDirect3DDevice9 *device)
5637 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5638 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5639 HRESULT hr;
5640 DWORD color;
5641 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5642 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5643 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5645 DWORD shader_code_11[] = {
5646 0xffff0101, /* ps_1_1 */
5647 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5648 0x00000040, 0xb00f0000, /* texcoord t0 */
5649 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5650 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5651 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5652 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5653 0x0000ffff /* end */
5655 DWORD shader_code_12[] = {
5656 0xffff0102, /* ps_1_2 */
5657 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5658 0x00000040, 0xb00f0000, /* texcoord t0 */
5659 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5660 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5661 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5662 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5663 0x0000ffff /* end */
5665 DWORD shader_code_13[] = {
5666 0xffff0103, /* ps_1_3 */
5667 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5668 0x00000040, 0xb00f0000, /* texcoord t0 */
5669 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5670 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5671 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5672 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5673 0x0000ffff /* end */
5675 DWORD shader_code_14[] = {
5676 0xffff0104, /* ps_1_3 */
5677 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5678 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5679 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5680 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5681 0x0000ffff /* end */
5684 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5685 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5686 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5687 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5688 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5689 * well enough.
5691 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5692 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5693 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5694 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5696 DWORD shader_code_11_coissue[] = {
5697 0xffff0101, /* ps_1_1 */
5698 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5699 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5700 0x00000040, 0xb00f0000, /* texcoord t0 */
5701 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5702 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5703 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5704 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5705 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5706 /* 0x40000000 = D3DSI_COISSUE */
5707 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5708 0x0000ffff /* end */
5710 DWORD shader_code_12_coissue[] = {
5711 0xffff0102, /* ps_1_2 */
5712 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5713 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5714 0x00000040, 0xb00f0000, /* texcoord t0 */
5715 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5716 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5717 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5718 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5719 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5720 /* 0x40000000 = D3DSI_COISSUE */
5721 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5722 0x0000ffff /* end */
5724 DWORD shader_code_13_coissue[] = {
5725 0xffff0103, /* ps_1_3 */
5726 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5727 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5728 0x00000040, 0xb00f0000, /* texcoord t0 */
5729 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5730 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5731 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5732 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5733 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5734 /* 0x40000000 = D3DSI_COISSUE */
5735 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5736 0x0000ffff /* end */
5738 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5739 * compare against 0.5
5741 DWORD shader_code_14_coissue[] = {
5742 0xffff0104, /* ps_1_4 */
5743 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5744 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5745 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5746 /* 0x40000000 = D3DSI_COISSUE */
5747 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5748 0x0000ffff /* end */
5750 float quad1[] = {
5751 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5752 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5753 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5754 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5756 float quad2[] = {
5757 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5758 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5759 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5760 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5762 float quad3[] = {
5763 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5764 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5765 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5766 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5768 float quad4[] = {
5769 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5770 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5771 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5772 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5774 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5775 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5776 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5777 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5779 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5780 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5782 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5783 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5784 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5785 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5786 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5787 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5788 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5789 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5790 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5791 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5792 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5793 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5794 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5795 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5796 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5797 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5799 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5801 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5802 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5803 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5804 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5806 hr = IDirect3DDevice9_BeginScene(device);
5807 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5808 if(SUCCEEDED(hr))
5810 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5811 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5813 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5815 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5816 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5818 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5820 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5821 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5823 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5825 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5826 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5828 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5830 hr = IDirect3DDevice9_EndScene(device);
5831 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5834 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5835 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5837 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5838 color = getPixelColor(device, 158, 118);
5839 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5840 color = getPixelColor(device, 162, 118);
5841 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5842 color = getPixelColor(device, 158, 122);
5843 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5844 color = getPixelColor(device, 162, 122);
5845 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5847 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5848 color = getPixelColor(device, 158, 358);
5849 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5850 color = getPixelColor(device, 162, 358);
5851 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5852 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5853 color = getPixelColor(device, 158, 362);
5854 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5855 color = getPixelColor(device, 162, 362);
5856 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5857 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5859 /* 1.2 shader */
5860 color = getPixelColor(device, 478, 358);
5861 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5862 color = getPixelColor(device, 482, 358);
5863 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5864 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5865 color = getPixelColor(device, 478, 362);
5866 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5867 color = getPixelColor(device, 482, 362);
5868 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5869 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5871 /* 1.3 shader */
5872 color = getPixelColor(device, 478, 118);
5873 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5874 color = getPixelColor(device, 482, 118);
5875 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5876 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5877 color = getPixelColor(device, 478, 122);
5878 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5879 color = getPixelColor(device, 482, 122);
5880 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5881 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5884 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5887 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5888 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5889 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5890 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5891 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5893 hr = IDirect3DDevice9_BeginScene(device);
5894 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5895 if(SUCCEEDED(hr))
5897 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5898 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5899 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5900 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5902 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5903 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5905 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5907 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5908 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5910 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5912 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5915 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5917 hr = IDirect3DDevice9_EndScene(device);
5918 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5921 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5922 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5924 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5925 * that we swapped the values in c1 and c2 to make the other tests return some color
5927 color = getPixelColor(device, 158, 118);
5928 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5929 color = getPixelColor(device, 162, 118);
5930 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5931 color = getPixelColor(device, 158, 122);
5932 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5933 color = getPixelColor(device, 162, 122);
5934 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5936 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5937 * (The Win7 nvidia driver always selects c2)
5939 color = getPixelColor(device, 158, 358);
5940 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5941 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5942 color = getPixelColor(device, 162, 358);
5943 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5944 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5945 color = getPixelColor(device, 158, 362);
5946 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5947 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5948 color = getPixelColor(device, 162, 362);
5949 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5950 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5952 /* 1.2 shader */
5953 color = getPixelColor(device, 478, 358);
5954 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5955 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5956 color = getPixelColor(device, 482, 358);
5957 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5958 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5959 color = getPixelColor(device, 478, 362);
5960 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5961 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5962 color = getPixelColor(device, 482, 362);
5963 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5964 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5966 /* 1.3 shader */
5967 color = getPixelColor(device, 478, 118);
5968 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5969 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5970 color = getPixelColor(device, 482, 118);
5971 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5972 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5973 color = getPixelColor(device, 478, 122);
5974 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5975 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5976 color = getPixelColor(device, 482, 122);
5977 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5978 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5980 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5981 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5983 IDirect3DPixelShader9_Release(shader_14_coissue);
5984 IDirect3DPixelShader9_Release(shader_13_coissue);
5985 IDirect3DPixelShader9_Release(shader_12_coissue);
5986 IDirect3DPixelShader9_Release(shader_11_coissue);
5987 IDirect3DPixelShader9_Release(shader_14);
5988 IDirect3DPixelShader9_Release(shader_13);
5989 IDirect3DPixelShader9_Release(shader_12);
5990 IDirect3DPixelShader9_Release(shader_11);
5993 static void nested_loop_test(IDirect3DDevice9 *device) {
5994 const DWORD shader_code[] = {
5995 0xffff0300, /* ps_3_0 */
5996 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5997 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5998 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5999 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6000 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6001 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6002 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6003 0x0000001d, /* endloop */
6004 0x0000001d, /* endloop */
6005 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6006 0x0000ffff /* end */
6008 const DWORD vshader_code[] = {
6009 0xfffe0300, /* vs_3_0 */
6010 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6011 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6012 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6013 0x0000ffff /* end */
6015 IDirect3DPixelShader9 *shader;
6016 IDirect3DVertexShader9 *vshader;
6017 HRESULT hr;
6018 DWORD color;
6019 const float quad[] = {
6020 -1.0, -1.0, 0.1,
6021 1.0, -1.0, 0.1,
6022 -1.0, 1.0, 0.1,
6023 1.0, 1.0, 0.1
6026 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6027 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6028 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6029 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6030 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6032 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6033 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6034 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6036 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6037 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6039 hr = IDirect3DDevice9_BeginScene(device);
6040 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6041 if(SUCCEEDED(hr))
6043 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6044 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6045 hr = IDirect3DDevice9_EndScene(device);
6046 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6049 color = getPixelColor(device, 360, 240);
6050 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6051 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6053 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6054 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6056 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6057 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6058 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6059 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6060 IDirect3DPixelShader9_Release(shader);
6061 IDirect3DVertexShader9_Release(vshader);
6064 struct varying_test_struct
6066 const DWORD *shader_code;
6067 IDirect3DPixelShader9 *shader;
6068 DWORD color, color_rhw;
6069 const char *name;
6070 BOOL todo, todo_rhw;
6073 struct hugeVertex
6075 float pos_x, pos_y, pos_z, rhw;
6076 float weight_1, weight_2, weight_3, weight_4;
6077 float index_1, index_2, index_3, index_4;
6078 float normal_1, normal_2, normal_3, normal_4;
6079 float fog_1, fog_2, fog_3, fog_4;
6080 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
6081 float tangent_1, tangent_2, tangent_3, tangent_4;
6082 float binormal_1, binormal_2, binormal_3, binormal_4;
6083 float depth_1, depth_2, depth_3, depth_4;
6084 DWORD diffuse, specular;
6087 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6088 /* dcl_position: fails to compile */
6089 const DWORD blendweight_code[] = {
6090 0xffff0300, /* ps_3_0 */
6091 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6092 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6093 0x0000ffff /* end */
6095 const DWORD blendindices_code[] = {
6096 0xffff0300, /* ps_3_0 */
6097 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6098 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6099 0x0000ffff /* end */
6101 const DWORD normal_code[] = {
6102 0xffff0300, /* ps_3_0 */
6103 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6104 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6105 0x0000ffff /* end */
6107 /* psize: fails? */
6108 const DWORD texcoord0_code[] = {
6109 0xffff0300, /* ps_3_0 */
6110 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6111 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6112 0x0000ffff /* end */
6114 const DWORD tangent_code[] = {
6115 0xffff0300, /* ps_3_0 */
6116 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6117 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6118 0x0000ffff /* end */
6120 const DWORD binormal_code[] = {
6121 0xffff0300, /* ps_3_0 */
6122 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6123 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6124 0x0000ffff /* end */
6126 /* tessfactor: fails */
6127 /* positiont: fails */
6128 const DWORD color_code[] = {
6129 0xffff0300, /* ps_3_0 */
6130 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6131 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6132 0x0000ffff /* end */
6134 const DWORD fog_code[] = {
6135 0xffff0300, /* ps_3_0 */
6136 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
6137 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6138 0x0000ffff /* end */
6140 const DWORD depth_code[] = {
6141 0xffff0300, /* ps_3_0 */
6142 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
6143 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6144 0x0000ffff /* end */
6146 const DWORD specular_code[] = {
6147 0xffff0300, /* ps_3_0 */
6148 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
6149 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6150 0x0000ffff /* end */
6152 /* sample: fails */
6154 struct varying_test_struct tests[] = {
6155 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
6156 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
6157 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
6158 /* Why does dx not forward the texcoord? */
6159 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
6160 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
6161 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
6162 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
6163 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
6164 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
6165 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
6167 /* Declare a monster vertex type :-) */
6168 static const D3DVERTEXELEMENT9 decl_elements[] = {
6169 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6170 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
6171 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
6172 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
6173 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
6174 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6175 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
6176 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
6177 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
6178 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6179 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
6180 D3DDECL_END()
6182 struct hugeVertex data[4] = {
6184 -1.0, -1.0, 0.1, 1.0,
6185 0.1, 0.1, 0.1, 0.1,
6186 0.2, 0.2, 0.2, 0.2,
6187 0.3, 0.3, 0.3, 0.3,
6188 0.4, 0.4, 0.4, 0.4,
6189 0.50, 0.55, 0.55, 0.55,
6190 0.6, 0.6, 0.6, 0.7,
6191 0.7, 0.7, 0.7, 0.6,
6192 0.8, 0.8, 0.8, 0.8,
6193 0xe6e6e6e6, /* 0.9 * 256 */
6194 0x224488ff /* Nothing special */
6197 1.0, -1.0, 0.1, 1.0,
6198 0.1, 0.1, 0.1, 0.1,
6199 0.2, 0.2, 0.2, 0.2,
6200 0.3, 0.3, 0.3, 0.3,
6201 0.4, 0.4, 0.4, 0.4,
6202 0.50, 0.55, 0.55, 0.55,
6203 0.6, 0.6, 0.6, 0.7,
6204 0.7, 0.7, 0.7, 0.6,
6205 0.8, 0.8, 0.8, 0.8,
6206 0xe6e6e6e6, /* 0.9 * 256 */
6207 0x224488ff /* Nothing special */
6210 -1.0, 1.0, 0.1, 1.0,
6211 0.1, 0.1, 0.1, 0.1,
6212 0.2, 0.2, 0.2, 0.2,
6213 0.3, 0.3, 0.3, 0.3,
6214 0.4, 0.4, 0.4, 0.4,
6215 0.50, 0.55, 0.55, 0.55,
6216 0.6, 0.6, 0.6, 0.7,
6217 0.7, 0.7, 0.7, 0.6,
6218 0.8, 0.8, 0.8, 0.8,
6219 0xe6e6e6e6, /* 0.9 * 256 */
6220 0x224488ff /* Nothing special */
6223 1.0, 1.0, 0.1, 1.0,
6224 0.1, 0.1, 0.1, 0.1,
6225 0.2, 0.2, 0.2, 0.2,
6226 0.3, 0.3, 0.3, 0.3,
6227 0.4, 0.4, 0.4, 0.4,
6228 0.50, 0.55, 0.55, 0.55,
6229 0.6, 0.6, 0.6, 0.7,
6230 0.7, 0.7, 0.7, 0.6,
6231 0.8, 0.8, 0.8, 0.8,
6232 0xe6e6e6e6, /* 0.9 * 256 */
6233 0x224488ff /* Nothing special */
6236 struct hugeVertex data2[4];
6237 IDirect3DVertexDeclaration9 *decl;
6238 HRESULT hr;
6239 unsigned int i;
6240 DWORD color, r, g, b, r_e, g_e, b_e;
6242 memcpy(data2, data, sizeof(data2));
6243 data2[0].pos_x = 0; data2[0].pos_y = 0;
6244 data2[1].pos_x = 640; data2[1].pos_y = 0;
6245 data2[2].pos_x = 0; data2[2].pos_y = 480;
6246 data2[3].pos_x = 640; data2[3].pos_y = 480;
6248 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6249 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6250 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6251 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6253 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6255 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6257 tests[i].name, hr);
6260 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6261 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6264 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6265 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6267 hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6268 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6270 hr = IDirect3DDevice9_BeginScene(device);
6271 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6272 if(SUCCEEDED(hr))
6274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6275 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6276 hr = IDirect3DDevice9_EndScene(device);
6277 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6280 color = getPixelColor(device, 360, 240);
6281 r = color & 0x00ff0000 >> 16;
6282 g = color & 0x0000ff00 >> 8;
6283 b = color & 0x000000ff;
6284 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6285 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
6286 b_e = tests[i].color_rhw & 0x000000ff;
6288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6291 if(tests[i].todo_rhw) {
6292 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6293 * pipeline
6295 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6296 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6297 tests[i].name, color, tests[i].color_rhw);
6298 } else {
6299 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6300 "Test %s returned color 0x%08x, expected 0x%08x\n",
6301 tests[i].name, color, tests[i].color_rhw);
6305 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6307 IDirect3DPixelShader9_Release(tests[i].shader);
6310 IDirect3DVertexDeclaration9_Release(decl);
6313 static void test_compare_instructions(IDirect3DDevice9 *device)
6315 DWORD shader_sge_vec_code[] = {
6316 0xfffe0101, /* vs_1_1 */
6317 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6318 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6319 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6320 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6321 0x0000ffff /* end */
6323 DWORD shader_slt_vec_code[] = {
6324 0xfffe0101, /* vs_1_1 */
6325 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6326 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6327 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6328 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6329 0x0000ffff /* end */
6331 DWORD shader_sge_scalar_code[] = {
6332 0xfffe0101, /* vs_1_1 */
6333 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6334 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6335 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6336 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6337 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6338 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6339 0x0000ffff /* end */
6341 DWORD shader_slt_scalar_code[] = {
6342 0xfffe0101, /* vs_1_1 */
6343 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6344 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6345 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6346 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6347 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6348 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6349 0x0000ffff /* end */
6351 IDirect3DVertexShader9 *shader_sge_vec;
6352 IDirect3DVertexShader9 *shader_slt_vec;
6353 IDirect3DVertexShader9 *shader_sge_scalar;
6354 IDirect3DVertexShader9 *shader_slt_scalar;
6355 HRESULT hr, color;
6356 float quad1[] = {
6357 -1.0, -1.0, 0.1,
6358 0.0, -1.0, 0.1,
6359 -1.0, 0.0, 0.1,
6360 0.0, 0.0, 0.1
6362 float quad2[] = {
6363 0.0, -1.0, 0.1,
6364 1.0, -1.0, 0.1,
6365 0.0, 0.0, 0.1,
6366 1.0, 0.0, 0.1
6368 float quad3[] = {
6369 -1.0, 0.0, 0.1,
6370 0.0, 0.0, 0.1,
6371 -1.0, 1.0, 0.1,
6372 0.0, 1.0, 0.1
6374 float quad4[] = {
6375 0.0, 0.0, 0.1,
6376 1.0, 0.0, 0.1,
6377 0.0, 1.0, 0.1,
6378 1.0, 1.0, 0.1
6380 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6381 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6384 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6386 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6387 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6388 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6389 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6393 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6394 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6395 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6396 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6397 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6399 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6401 hr = IDirect3DDevice9_BeginScene(device);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6403 if(SUCCEEDED(hr))
6405 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6408 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6410 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6413 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6415 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6418 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6420 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6421 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6423 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6424 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6425 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6426 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6428 hr = IDirect3DDevice9_EndScene(device);
6429 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6432 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6435 color = getPixelColor(device, 160, 360);
6436 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6437 color = getPixelColor(device, 480, 360);
6438 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6439 color = getPixelColor(device, 160, 120);
6440 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6441 color = getPixelColor(device, 480, 160);
6442 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6444 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6445 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6447 IDirect3DVertexShader9_Release(shader_sge_vec);
6448 IDirect3DVertexShader9_Release(shader_slt_vec);
6449 IDirect3DVertexShader9_Release(shader_sge_scalar);
6450 IDirect3DVertexShader9_Release(shader_slt_scalar);
6453 static void test_vshader_input(IDirect3DDevice9 *device)
6455 static const DWORD swapped_shader_code_3[] =
6457 0xfffe0300, /* vs_3_0 */
6458 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6459 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6460 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6461 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6462 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6463 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6464 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6465 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6466 0x0000ffff /* end */
6468 static const DWORD swapped_shader_code_1[] =
6470 0xfffe0101, /* vs_1_1 */
6471 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6472 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6473 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6474 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6475 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6476 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6477 0x0000ffff /* end */
6479 static const DWORD swapped_shader_code_2[] =
6481 0xfffe0200, /* vs_2_0 */
6482 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6483 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
6484 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
6485 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
6486 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
6487 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
6488 0x0000ffff /* end */
6490 static const DWORD texcoord_color_shader_code_3[] =
6492 0xfffe0300, /* vs_3_0 */
6493 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6494 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6495 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6496 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6497 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6498 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6499 0x0000ffff /* end */
6501 static const DWORD texcoord_color_shader_code_2[] =
6503 0xfffe0200, /* vs_2_0 */
6504 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6505 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6506 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6507 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6508 0x0000ffff /* end */
6510 static const DWORD texcoord_color_shader_code_1[] =
6512 0xfffe0101, /* vs_1_1 */
6513 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6514 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6515 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6516 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6517 0x0000ffff /* end */
6519 static const DWORD color_color_shader_code_3[] =
6521 0xfffe0300, /* vs_3_0 */
6522 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6523 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6524 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6525 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6526 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6527 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6528 0x0000ffff /* end */
6530 static const DWORD color_color_shader_code_2[] =
6532 0xfffe0200, /* vs_2_0 */
6533 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6534 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6535 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6536 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6537 0x0000ffff /* end */
6539 static const DWORD color_color_shader_code_1[] =
6541 0xfffe0101, /* vs_1_1 */
6542 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6543 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6544 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6545 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6546 0x0000ffff /* end */
6548 static const DWORD ps3_code[] =
6550 0xffff0300, /* ps_3_0 */
6551 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6552 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6553 0x0000ffff /* end */
6555 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6556 IDirect3DPixelShader9 *ps;
6557 HRESULT hr;
6558 DWORD color;
6559 float quad1[] = {
6560 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6561 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6562 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6563 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6565 float quad2[] = {
6566 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6567 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6568 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6569 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6571 float quad3[] = {
6572 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6573 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6574 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6575 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6577 float quad4[] = {
6578 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6579 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6580 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6581 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6583 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6584 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6585 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6586 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6587 D3DDECL_END()
6589 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6590 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6591 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6592 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6593 D3DDECL_END()
6595 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6596 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6597 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6598 D3DDECL_END()
6600 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6601 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6602 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6603 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6604 D3DDECL_END()
6606 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6607 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6608 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6609 D3DDECL_END()
6611 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6612 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6613 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6614 D3DDECL_END()
6616 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6617 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6618 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6619 D3DDECL_END()
6621 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6622 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6623 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6624 D3DDECL_END()
6626 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6627 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6628 unsigned int i;
6629 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6630 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6632 struct vertex quad1_color[] = {
6633 {-1.0, -1.0, 0.1, 0x00ff8040},
6634 { 0.0, -1.0, 0.1, 0x00ff8040},
6635 {-1.0, 0.0, 0.1, 0x00ff8040},
6636 { 0.0, 0.0, 0.1, 0x00ff8040}
6638 struct vertex quad2_color[] = {
6639 { 0.0, -1.0, 0.1, 0x00ff8040},
6640 { 1.0, -1.0, 0.1, 0x00ff8040},
6641 { 0.0, 0.0, 0.1, 0x00ff8040},
6642 { 1.0, 0.0, 0.1, 0x00ff8040}
6644 struct vertex quad3_color[] = {
6645 {-1.0, 0.0, 0.1, 0x00ff8040},
6646 { 0.0, 0.0, 0.1, 0x00ff8040},
6647 {-1.0, 1.0, 0.1, 0x00ff8040},
6648 { 0.0, 1.0, 0.1, 0x00ff8040}
6650 float quad4_color[] = {
6651 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6652 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6653 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6654 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6657 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6658 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6659 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6660 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6661 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6662 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6663 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6666 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6667 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6668 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6669 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6670 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6671 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6672 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6673 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6675 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6676 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6678 for(i = 1; i <= 3; i++) {
6679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6680 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6681 if(i == 3) {
6682 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6683 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6684 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6685 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6686 } else if(i == 2){
6687 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6688 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6689 } else if(i == 1) {
6690 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6694 hr = IDirect3DDevice9_BeginScene(device);
6695 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6696 if(SUCCEEDED(hr))
6698 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6701 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6704 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6706 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6707 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6709 if(i == 3 || i == 2) {
6710 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6711 } else if(i == 1) {
6712 /* Succeeds or fails, depending on SW or HW vertex processing */
6713 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6716 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6719 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6721 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6722 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6723 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6724 if(i == 3 || i == 2) {
6725 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6726 } else if(i == 1) {
6727 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6730 hr = IDirect3DDevice9_EndScene(device);
6731 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6734 if(i == 3 || i == 2) {
6735 color = getPixelColor(device, 160, 360);
6736 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6737 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6739 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6740 color = getPixelColor(device, 480, 360);
6741 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6742 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6743 color = getPixelColor(device, 160, 120);
6744 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6745 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6746 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6748 color = getPixelColor(device, 480, 160);
6749 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6750 } else if(i == 1) {
6751 color = getPixelColor(device, 160, 360);
6752 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6753 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6754 color = getPixelColor(device, 480, 360);
6755 /* Accept the clear color as well in this case, since SW VP returns an error */
6756 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6757 color = getPixelColor(device, 160, 120);
6758 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6759 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6760 color = getPixelColor(device, 480, 160);
6761 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6764 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6765 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6767 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6768 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6770 /* Now find out if the whole streams are re-read, or just the last active value for the
6771 * vertices is used.
6773 hr = IDirect3DDevice9_BeginScene(device);
6774 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6775 if(SUCCEEDED(hr))
6777 float quad1_modified[] = {
6778 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6779 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6780 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6781 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6783 float quad2_modified[] = {
6784 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6785 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6786 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6787 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6790 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6791 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6793 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6796 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6798 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6799 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6801 if(i == 3 || i == 2) {
6802 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6803 } else if(i == 1) {
6804 /* Succeeds or fails, depending on SW or HW vertex processing */
6805 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6808 hr = IDirect3DDevice9_EndScene(device);
6809 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6812 color = getPixelColor(device, 480, 350);
6813 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6814 * as well.
6816 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6817 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6818 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6819 * refrast's result.
6821 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6823 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6824 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6827 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6829 IDirect3DDevice9_SetVertexShader(device, NULL);
6830 IDirect3DDevice9_SetPixelShader(device, NULL);
6831 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6833 IDirect3DVertexShader9_Release(swapped_shader);
6836 for(i = 1; i <= 3; i++) {
6837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6838 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6839 if(i == 3) {
6840 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6841 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6842 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6843 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6844 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6845 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6846 } else if(i == 2){
6847 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6848 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6849 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6850 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6851 } else if(i == 1) {
6852 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6853 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6854 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6855 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6858 hr = IDirect3DDevice9_BeginScene(device);
6859 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6860 if(SUCCEEDED(hr))
6862 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6863 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6864 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6865 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6867 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6869 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6870 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6872 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6873 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6874 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6875 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6877 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6879 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6880 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6881 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6882 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6884 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6886 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6887 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6889 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6891 hr = IDirect3DDevice9_EndScene(device);
6892 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6894 IDirect3DDevice9_SetVertexShader(device, NULL);
6895 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6896 IDirect3DDevice9_SetPixelShader(device, NULL);
6898 color = getPixelColor(device, 160, 360);
6899 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6900 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6901 color = getPixelColor(device, 480, 360);
6902 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6903 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6904 color = getPixelColor(device, 160, 120);
6905 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6906 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6907 color = getPixelColor(device, 480, 160);
6908 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6909 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6911 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6912 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6914 IDirect3DVertexShader9_Release(texcoord_color_shader);
6915 IDirect3DVertexShader9_Release(color_color_shader);
6918 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6919 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6920 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6921 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6923 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6924 IDirect3DVertexDeclaration9_Release(decl_color_color);
6925 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6926 IDirect3DVertexDeclaration9_Release(decl_color_float);
6928 IDirect3DPixelShader9_Release(ps);
6931 static void srgbtexture_test(IDirect3DDevice9 *device)
6933 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6934 * texture stage state to render a quad using that texture. The resulting
6935 * color components should be 0x36 (~ 0.21), per this formula:
6936 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6937 * This is true where srgb_color > 0.04045.
6939 IDirect3D9 *d3d = NULL;
6940 HRESULT hr;
6941 LPDIRECT3DTEXTURE9 texture = NULL;
6942 LPDIRECT3DSURFACE9 surface = NULL;
6943 D3DLOCKED_RECT lr;
6944 DWORD color;
6945 float quad[] = {
6946 -1.0, 1.0, 0.0, 0.0, 0.0,
6947 1.0, 1.0, 0.0, 1.0, 0.0,
6948 -1.0, -1.0, 0.0, 0.0, 1.0,
6949 1.0, -1.0, 0.0, 1.0, 1.0,
6953 memset(&lr, 0, sizeof(lr));
6954 IDirect3DDevice9_GetDirect3D(device, &d3d);
6955 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6956 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6957 D3DFMT_A8R8G8B8) != D3D_OK) {
6958 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6959 goto out;
6962 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6963 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6964 &texture, NULL);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6966 if(!texture) {
6967 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6968 goto out;
6970 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6971 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6973 fill_surface(surface, 0xff7f7f7f);
6974 IDirect3DSurface9_Release(surface);
6976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6977 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6978 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6979 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6981 hr = IDirect3DDevice9_BeginScene(device);
6982 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6983 if(SUCCEEDED(hr))
6985 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6986 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6988 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6989 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6995 hr = IDirect3DDevice9_EndScene(device);
6996 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6999 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7000 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7001 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7002 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7004 color = getPixelColor(device, 320, 240);
7005 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7007 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7008 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7010 out:
7011 if(texture) IDirect3DTexture9_Release(texture);
7012 IDirect3D9_Release(d3d);
7015 static void shademode_test(IDirect3DDevice9 *device)
7017 /* Render a quad and try all of the different fixed function shading models. */
7018 HRESULT hr;
7019 DWORD color0, color1;
7020 DWORD color0_gouraud = 0, color1_gouraud = 0;
7021 DWORD shademode = D3DSHADE_FLAT;
7022 DWORD primtype = D3DPT_TRIANGLESTRIP;
7023 LPVOID data = NULL;
7024 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
7025 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
7026 UINT i, j;
7027 struct vertex quad_strip[] =
7029 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7030 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7031 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7032 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7034 struct vertex quad_list[] =
7036 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7037 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7038 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7040 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7041 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7042 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7045 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7046 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7047 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7048 if (FAILED(hr)) goto bail;
7050 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7051 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7052 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7053 if (FAILED(hr)) goto bail;
7055 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7056 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7059 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7061 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7062 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7063 memcpy(data, quad_strip, sizeof(quad_strip));
7064 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7065 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7067 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7068 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7069 memcpy(data, quad_list, sizeof(quad_list));
7070 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7071 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7073 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
7074 * the color fixups we have to do for FLAT shading will be dependent on that. */
7075 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7076 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7078 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7079 for (j=0; j<2; j++) {
7081 /* Inner loop just changes the D3DRS_SHADEMODE */
7082 for (i=0; i<3; i++) {
7083 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7084 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7089 hr = IDirect3DDevice9_BeginScene(device);
7090 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7091 if(SUCCEEDED(hr))
7093 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7094 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7096 hr = IDirect3DDevice9_EndScene(device);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7100 /* Sample two spots from the output */
7101 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7102 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7103 switch(shademode) {
7104 case D3DSHADE_FLAT:
7105 /* Should take the color of the first vertex of each triangle */
7106 if (0)
7108 /* This test depends on EXT_provoking_vertex being
7109 * available. This extension is currently (20090810)
7110 * not common enough to let the test fail if it isn't
7111 * present. */
7112 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7113 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7115 shademode = D3DSHADE_GOURAUD;
7116 break;
7117 case D3DSHADE_GOURAUD:
7118 /* Should be an interpolated blend */
7120 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7121 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7122 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7123 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7125 color0_gouraud = color0;
7126 color1_gouraud = color1;
7128 shademode = D3DSHADE_PHONG;
7129 break;
7130 case D3DSHADE_PHONG:
7131 /* Should be the same as GOURAUD, since no hardware implements this */
7132 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7133 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7134 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7135 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7137 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7138 color0_gouraud, color0);
7139 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7140 color1_gouraud, color1);
7141 break;
7145 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7146 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7148 /* Now, do it all over again with a TRIANGLELIST */
7149 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7150 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7151 primtype = D3DPT_TRIANGLELIST;
7152 shademode = D3DSHADE_FLAT;
7155 bail:
7156 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7157 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7161 if (vb_strip)
7162 IDirect3DVertexBuffer9_Release(vb_strip);
7163 if (vb_list)
7164 IDirect3DVertexBuffer9_Release(vb_list);
7167 static void alpha_test(IDirect3DDevice9 *device)
7169 HRESULT hr;
7170 IDirect3DTexture9 *offscreenTexture;
7171 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7172 DWORD color;
7174 struct vertex quad1[] =
7176 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7177 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7178 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7179 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7181 struct vertex quad2[] =
7183 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7184 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7185 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7186 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7188 static const float composite_quad[][5] = {
7189 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7190 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7191 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7192 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7195 /* Clear the render target with alpha = 0.5 */
7196 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7197 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7199 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7200 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7202 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7203 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7204 if(!backbuffer) {
7205 goto out;
7208 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7209 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7210 if(!offscreen) {
7211 goto out;
7214 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7215 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7217 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7218 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7219 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7220 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7221 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7222 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7223 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7224 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7226 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7228 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7229 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7230 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7232 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7235 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7236 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7238 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7243 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7245 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7247 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7248 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7249 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7250 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7251 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7253 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7258 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7259 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7260 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7265 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7267 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7269 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7270 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7272 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7273 * Disable alpha blending for the final composition
7275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7276 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7277 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7278 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7280 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7281 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7283 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7284 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7285 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7287 hr = IDirect3DDevice9_EndScene(device);
7288 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7291 color = getPixelColor(device, 160, 360);
7292 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7293 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7295 color = getPixelColor(device, 160, 120);
7296 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7297 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7299 color = getPixelColor(device, 480, 360);
7300 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7301 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7303 color = getPixelColor(device, 480, 120);
7304 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7305 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7307 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7309 out:
7310 /* restore things */
7311 if(backbuffer) {
7312 IDirect3DSurface9_Release(backbuffer);
7314 if(offscreenTexture) {
7315 IDirect3DTexture9_Release(offscreenTexture);
7317 if(offscreen) {
7318 IDirect3DSurface9_Release(offscreen);
7322 struct vertex_shortcolor {
7323 float x, y, z;
7324 unsigned short r, g, b, a;
7326 struct vertex_floatcolor {
7327 float x, y, z;
7328 float r, g, b, a;
7331 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7333 HRESULT hr;
7334 BOOL s_ok, ub_ok, f_ok;
7335 DWORD color, size, i;
7336 void *data;
7337 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7338 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7339 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7340 D3DDECL_END()
7342 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7343 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7344 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7345 D3DDECL_END()
7347 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7348 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7349 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7350 D3DDECL_END()
7352 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7353 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7354 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7355 D3DDECL_END()
7357 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7358 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7359 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7360 D3DDECL_END()
7362 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7363 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7364 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7365 D3DDECL_END()
7367 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7368 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7369 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7370 D3DDECL_END()
7372 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7373 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7374 IDirect3DVertexBuffer9 *vb, *vb2;
7375 struct vertex quad1[] = /* D3DCOLOR */
7377 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
7378 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7379 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
7380 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7382 struct vertex quad2[] = /* UBYTE4N */
7384 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
7385 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
7386 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
7387 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
7389 struct vertex_shortcolor quad3[] = /* short */
7391 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7392 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7393 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7394 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
7396 struct vertex_floatcolor quad4[] =
7398 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7399 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7400 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7401 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
7403 DWORD colors[] = {
7404 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7405 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7406 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7407 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7408 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7409 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7410 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7411 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7412 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7413 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7414 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7415 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7416 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7417 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7418 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7419 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
7421 float quads[] = {
7422 -1.0, -1.0, 0.1,
7423 -1.0, 0.0, 0.1,
7424 0.0, -1.0, 0.1,
7425 0.0, 0.0, 0.1,
7427 0.0, -1.0, 0.1,
7428 0.0, 0.0, 0.1,
7429 1.0, -1.0, 0.1,
7430 1.0, 0.0, 0.1,
7432 0.0, 0.0, 0.1,
7433 0.0, 1.0, 0.1,
7434 1.0, 0.0, 0.1,
7435 1.0, 1.0, 0.1,
7437 -1.0, 0.0, 0.1,
7438 -1.0, 1.0, 0.1,
7439 0.0, 0.0, 0.1,
7440 0.0, 1.0, 0.1
7442 struct tvertex quad_transformed[] = {
7443 { 90, 110, 0.1, 2.0, 0x00ffff00},
7444 { 570, 110, 0.1, 2.0, 0x00ffff00},
7445 { 90, 300, 0.1, 2.0, 0x00ffff00},
7446 { 570, 300, 0.1, 2.0, 0x00ffff00}
7448 D3DCAPS9 caps;
7450 memset(&caps, 0, sizeof(caps));
7451 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7452 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7454 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7455 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7457 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7458 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7459 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7460 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7461 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7462 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7463 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7464 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7465 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7466 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7467 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7468 } else {
7469 trace("D3DDTCAPS_UBYTE4N not supported\n");
7470 dcl_ubyte_2 = NULL;
7471 dcl_ubyte = NULL;
7473 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7474 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7475 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7476 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7478 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7479 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7480 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7481 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7483 hr = IDirect3DDevice9_BeginScene(device);
7484 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7485 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7486 if(SUCCEEDED(hr)) {
7487 if(dcl_color) {
7488 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7490 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7491 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7494 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7495 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7496 * using software vertex processing. Doh!
7498 if(dcl_ubyte) {
7499 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7500 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7501 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7502 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7503 ub_ok = SUCCEEDED(hr);
7506 if(dcl_short) {
7507 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7508 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7510 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7511 s_ok = SUCCEEDED(hr);
7514 if(dcl_float) {
7515 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7516 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7518 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7519 f_ok = SUCCEEDED(hr);
7522 hr = IDirect3DDevice9_EndScene(device);
7523 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7526 if(dcl_short) {
7527 color = getPixelColor(device, 480, 360);
7528 ok(color == 0x000000ff || !s_ok,
7529 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7531 if(dcl_ubyte) {
7532 color = getPixelColor(device, 160, 120);
7533 ok(color == 0x0000ffff || !ub_ok,
7534 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7536 if(dcl_color) {
7537 color = getPixelColor(device, 160, 360);
7538 ok(color == 0x00ffff00,
7539 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7541 if(dcl_float) {
7542 color = getPixelColor(device, 480, 120);
7543 ok(color == 0x00ff0000 || !f_ok,
7544 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7546 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7548 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7549 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7550 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7551 * whether the immediate mode code works
7553 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7554 hr = IDirect3DDevice9_BeginScene(device);
7555 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7556 if(SUCCEEDED(hr)) {
7557 if(dcl_color) {
7558 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7559 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7560 memcpy(data, quad1, sizeof(quad1));
7561 hr = IDirect3DVertexBuffer9_Unlock(vb);
7562 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7563 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7564 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7565 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7566 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7567 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7568 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7571 if(dcl_ubyte) {
7572 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7573 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7574 memcpy(data, quad2, sizeof(quad2));
7575 hr = IDirect3DVertexBuffer9_Unlock(vb);
7576 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7577 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7578 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7579 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7580 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7581 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7582 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7583 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7584 ub_ok = SUCCEEDED(hr);
7587 if(dcl_short) {
7588 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7589 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7590 memcpy(data, quad3, sizeof(quad3));
7591 hr = IDirect3DVertexBuffer9_Unlock(vb);
7592 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7593 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7594 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7595 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7596 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7597 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7598 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7599 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7600 s_ok = SUCCEEDED(hr);
7603 if(dcl_float) {
7604 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7605 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7606 memcpy(data, quad4, sizeof(quad4));
7607 hr = IDirect3DVertexBuffer9_Unlock(vb);
7608 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7609 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7610 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7611 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7612 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7613 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7614 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7615 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7616 f_ok = SUCCEEDED(hr);
7619 hr = IDirect3DDevice9_EndScene(device);
7620 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7623 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7624 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7625 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7626 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7628 if(dcl_short) {
7629 color = getPixelColor(device, 480, 360);
7630 ok(color == 0x000000ff || !s_ok,
7631 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7633 if(dcl_ubyte) {
7634 color = getPixelColor(device, 160, 120);
7635 ok(color == 0x0000ffff || !ub_ok,
7636 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7638 if(dcl_color) {
7639 color = getPixelColor(device, 160, 360);
7640 ok(color == 0x00ffff00,
7641 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7643 if(dcl_float) {
7644 color = getPixelColor(device, 480, 120);
7645 ok(color == 0x00ff0000 || !f_ok,
7646 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7648 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7653 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7654 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7655 memcpy(data, quad_transformed, sizeof(quad_transformed));
7656 hr = IDirect3DVertexBuffer9_Unlock(vb);
7657 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7659 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7660 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7662 hr = IDirect3DDevice9_BeginScene(device);
7663 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7664 if(SUCCEEDED(hr)) {
7665 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7666 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7667 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7670 hr = IDirect3DDevice9_EndScene(device);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7674 color = getPixelColor(device, 88, 108);
7675 ok(color == 0x000000ff,
7676 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7677 color = getPixelColor(device, 92, 108);
7678 ok(color == 0x000000ff,
7679 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7680 color = getPixelColor(device, 88, 112);
7681 ok(color == 0x000000ff,
7682 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7683 color = getPixelColor(device, 92, 112);
7684 ok(color == 0x00ffff00,
7685 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7687 color = getPixelColor(device, 568, 108);
7688 ok(color == 0x000000ff,
7689 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7690 color = getPixelColor(device, 572, 108);
7691 ok(color == 0x000000ff,
7692 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7693 color = getPixelColor(device, 568, 112);
7694 ok(color == 0x00ffff00,
7695 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7696 color = getPixelColor(device, 572, 112);
7697 ok(color == 0x000000ff,
7698 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7700 color = getPixelColor(device, 88, 298);
7701 ok(color == 0x000000ff,
7702 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7703 color = getPixelColor(device, 92, 298);
7704 ok(color == 0x00ffff00,
7705 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7706 color = getPixelColor(device, 88, 302);
7707 ok(color == 0x000000ff,
7708 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7709 color = getPixelColor(device, 92, 302);
7710 ok(color == 0x000000ff,
7711 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7713 color = getPixelColor(device, 568, 298);
7714 ok(color == 0x00ffff00,
7715 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7716 color = getPixelColor(device, 572, 298);
7717 ok(color == 0x000000ff,
7718 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7719 color = getPixelColor(device, 568, 302);
7720 ok(color == 0x000000ff,
7721 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7722 color = getPixelColor(device, 572, 302);
7723 ok(color == 0x000000ff,
7724 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7726 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7728 /* This test is pointless without those two declarations: */
7729 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7730 skip("color-ubyte switching test declarations aren't supported\n");
7731 goto out;
7734 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7735 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7736 memcpy(data, quads, sizeof(quads));
7737 hr = IDirect3DVertexBuffer9_Unlock(vb);
7738 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7739 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7740 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7741 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7742 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7743 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7744 memcpy(data, colors, sizeof(colors));
7745 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7746 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7748 for(i = 0; i < 2; i++) {
7749 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7750 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7752 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7753 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7754 if(i == 0) {
7755 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7756 } else {
7757 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7759 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7761 hr = IDirect3DDevice9_BeginScene(device);
7762 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7763 ub_ok = FALSE;
7764 if(SUCCEEDED(hr)) {
7765 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7766 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7767 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7768 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7769 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7770 ub_ok = SUCCEEDED(hr);
7772 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7773 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7774 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7775 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7777 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7778 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7779 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7780 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7781 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7782 ub_ok = (SUCCEEDED(hr) && ub_ok);
7784 hr = IDirect3DDevice9_EndScene(device);
7785 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7788 if(i == 0) {
7789 color = getPixelColor(device, 480, 360);
7790 ok(color == 0x00ff0000,
7791 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7792 color = getPixelColor(device, 160, 120);
7793 ok(color == 0x00ffffff,
7794 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7795 color = getPixelColor(device, 160, 360);
7796 ok(color == 0x000000ff || !ub_ok,
7797 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7798 color = getPixelColor(device, 480, 120);
7799 ok(color == 0x000000ff || !ub_ok,
7800 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7801 } else {
7802 color = getPixelColor(device, 480, 360);
7803 ok(color == 0x000000ff,
7804 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7805 color = getPixelColor(device, 160, 120);
7806 ok(color == 0x00ffffff,
7807 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7808 color = getPixelColor(device, 160, 360);
7809 ok(color == 0x00ff0000 || !ub_ok,
7810 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7811 color = getPixelColor(device, 480, 120);
7812 ok(color == 0x00ff0000 || !ub_ok,
7813 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7815 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7818 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7819 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7820 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7821 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7822 IDirect3DVertexBuffer9_Release(vb2);
7824 out:
7825 IDirect3DVertexBuffer9_Release(vb);
7826 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7827 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7828 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7829 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7830 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7831 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7832 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7835 struct vertex_float16color {
7836 float x, y, z;
7837 DWORD c1, c2;
7840 static void test_vshader_float16(IDirect3DDevice9 *device)
7842 HRESULT hr;
7843 DWORD color;
7844 void *data;
7845 static const D3DVERTEXELEMENT9 decl_elements[] = {
7846 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7847 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7848 D3DDECL_END()
7850 IDirect3DVertexDeclaration9 *vdecl = NULL;
7851 IDirect3DVertexBuffer9 *buffer = NULL;
7852 IDirect3DVertexShader9 *shader;
7853 DWORD shader_code[] = {
7854 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7855 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7856 0x90e40001, 0x0000ffff
7858 struct vertex_float16color quad[] = {
7859 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7860 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7861 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7862 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7864 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7865 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7866 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7867 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7869 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7870 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7871 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7872 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7874 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7875 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7876 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7877 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7880 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7883 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7884 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7885 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7886 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7887 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7888 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7890 hr = IDirect3DDevice9_BeginScene(device);
7891 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7892 if(SUCCEEDED(hr)) {
7893 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7896 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7898 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7899 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7900 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7902 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7904 hr = IDirect3DDevice9_EndScene(device);
7905 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7907 color = getPixelColor(device, 480, 360);
7908 ok(color == 0x00ff0000,
7909 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7910 color = getPixelColor(device, 160, 120);
7911 ok(color == 0x00000000,
7912 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7913 color = getPixelColor(device, 160, 360);
7914 ok(color == 0x0000ff00,
7915 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7916 color = getPixelColor(device, 480, 120);
7917 ok(color == 0x000000ff,
7918 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7919 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7921 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7922 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7924 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7925 D3DPOOL_MANAGED, &buffer, NULL);
7926 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7927 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7928 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7929 memcpy(data, quad, sizeof(quad));
7930 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7931 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7932 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7933 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7935 hr = IDirect3DDevice9_BeginScene(device);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7937 if(SUCCEEDED(hr)) {
7938 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7939 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7940 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7941 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7942 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7943 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7944 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7945 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7947 hr = IDirect3DDevice9_EndScene(device);
7948 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7951 color = getPixelColor(device, 480, 360);
7952 ok(color == 0x00ff0000,
7953 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7954 color = getPixelColor(device, 160, 120);
7955 ok(color == 0x00000000,
7956 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7957 color = getPixelColor(device, 160, 360);
7958 ok(color == 0x0000ff00,
7959 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7960 color = getPixelColor(device, 480, 120);
7961 ok(color == 0x000000ff,
7962 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7963 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7965 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7966 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7967 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7968 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7969 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7970 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7972 IDirect3DVertexDeclaration9_Release(vdecl);
7973 IDirect3DVertexShader9_Release(shader);
7974 IDirect3DVertexBuffer9_Release(buffer);
7977 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7979 D3DCAPS9 caps;
7980 IDirect3DTexture9 *texture;
7981 HRESULT hr;
7982 D3DLOCKED_RECT rect;
7983 unsigned int x, y;
7984 DWORD *dst, color;
7985 const float quad[] = {
7986 -1.0, -1.0, 0.1, -0.2, -0.2,
7987 1.0, -1.0, 0.1, 1.2, -0.2,
7988 -1.0, 1.0, 0.1, -0.2, 1.2,
7989 1.0, 1.0, 0.1, 1.2, 1.2
7991 memset(&caps, 0, sizeof(caps));
7993 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7994 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7995 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7997 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7998 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7999 "Card has conditional NP2 support without power of two restriction set\n");
8001 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8003 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8004 return;
8006 else
8008 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8009 return;
8012 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8013 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8015 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8016 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8018 memset(&rect, 0, sizeof(rect));
8019 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8020 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8021 for(y = 0; y < 10; y++) {
8022 for(x = 0; x < 10; x++) {
8023 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8024 if(x == 0 || x == 9 || y == 0 || y == 9) {
8025 *dst = 0x00ff0000;
8026 } else {
8027 *dst = 0x000000ff;
8031 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8032 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8034 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8035 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8036 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8037 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8038 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8039 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8041 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8043 hr = IDirect3DDevice9_BeginScene(device);
8044 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8045 if(SUCCEEDED(hr)) {
8046 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8047 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8049 hr = IDirect3DDevice9_EndScene(device);
8050 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8053 color = getPixelColor(device, 1, 1);
8054 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8055 color = getPixelColor(device, 639, 479);
8056 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8058 color = getPixelColor(device, 135, 101);
8059 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8060 color = getPixelColor(device, 140, 101);
8061 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8062 color = getPixelColor(device, 135, 105);
8063 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8064 color = getPixelColor(device, 140, 105);
8065 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8067 color = getPixelColor(device, 135, 376);
8068 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8069 color = getPixelColor(device, 140, 376);
8070 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8071 color = getPixelColor(device, 135, 379);
8072 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8073 color = getPixelColor(device, 140, 379);
8074 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8076 color = getPixelColor(device, 500, 101);
8077 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8078 color = getPixelColor(device, 504, 101);
8079 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8080 color = getPixelColor(device, 500, 105);
8081 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8082 color = getPixelColor(device, 504, 105);
8083 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8085 color = getPixelColor(device, 500, 376);
8086 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8087 color = getPixelColor(device, 504, 376);
8088 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8089 color = getPixelColor(device, 500, 380);
8090 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8091 color = getPixelColor(device, 504, 380);
8092 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8094 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8096 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8097 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8098 IDirect3DTexture9_Release(texture);
8101 static void vFace_register_test(IDirect3DDevice9 *device)
8103 HRESULT hr;
8104 DWORD color;
8105 const DWORD shader_code[] = {
8106 0xffff0300, /* ps_3_0 */
8107 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8108 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8109 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8110 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8111 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8112 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8113 0x0000ffff /* END */
8115 const DWORD vshader_code[] = {
8116 0xfffe0300, /* vs_3_0 */
8117 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8118 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8119 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8120 0x0000ffff /* end */
8122 IDirect3DPixelShader9 *shader;
8123 IDirect3DVertexShader9 *vshader;
8124 IDirect3DTexture9 *texture;
8125 IDirect3DSurface9 *surface, *backbuffer;
8126 const float quad[] = {
8127 -1.0, -1.0, 0.1,
8128 1.0, -1.0, 0.1,
8129 -1.0, 0.0, 0.1,
8131 1.0, -1.0, 0.1,
8132 1.0, 0.0, 0.1,
8133 -1.0, 0.0, 0.1,
8135 -1.0, 0.0, 0.1,
8136 -1.0, 1.0, 0.1,
8137 1.0, 0.0, 0.1,
8139 1.0, 0.0, 0.1,
8140 -1.0, 1.0, 0.1,
8141 1.0, 1.0, 0.1,
8143 const float blit[] = {
8144 0.0, -1.0, 0.1, 0.0, 0.0,
8145 1.0, -1.0, 0.1, 1.0, 0.0,
8146 0.0, 1.0, 0.1, 0.0, 1.0,
8147 1.0, 1.0, 0.1, 1.0, 1.0,
8150 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8152 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8153 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8154 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8156 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8157 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8158 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8159 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8160 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8161 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8163 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8164 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8165 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8168 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8170 hr = IDirect3DDevice9_BeginScene(device);
8171 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8172 if(SUCCEEDED(hr)) {
8173 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8174 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8175 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8176 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8177 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8179 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8180 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8181 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8182 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8183 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8185 /* Blit the texture onto the back buffer to make it visible */
8186 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8187 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8188 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8189 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8190 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8191 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8192 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8193 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8194 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8196 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8200 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8202 hr = IDirect3DDevice9_EndScene(device);
8203 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8206 color = getPixelColor(device, 160, 360);
8207 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8208 color = getPixelColor(device, 160, 120);
8209 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8210 color = getPixelColor(device, 480, 360);
8211 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8212 color = getPixelColor(device, 480, 120);
8213 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8214 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8215 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8217 IDirect3DDevice9_SetTexture(device, 0, NULL);
8218 IDirect3DPixelShader9_Release(shader);
8219 IDirect3DVertexShader9_Release(vshader);
8220 IDirect3DSurface9_Release(surface);
8221 IDirect3DSurface9_Release(backbuffer);
8222 IDirect3DTexture9_Release(texture);
8225 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8227 HRESULT hr;
8228 DWORD color;
8229 int i;
8230 D3DCAPS9 caps;
8231 BOOL L6V5U5_supported = FALSE;
8232 IDirect3DTexture9 *tex1, *tex2;
8233 D3DLOCKED_RECT locked_rect;
8235 static const float quad[][7] = {
8236 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8237 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8238 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8239 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8242 static const D3DVERTEXELEMENT9 decl_elements[] = {
8243 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8244 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8245 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8246 D3DDECL_END()
8249 /* use asymmetric matrix to test loading */
8250 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8251 float scale, offset;
8253 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8254 IDirect3DTexture9 *texture = NULL;
8256 memset(&caps, 0, sizeof(caps));
8257 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8258 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8259 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8260 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8261 return;
8262 } else {
8263 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8264 * They report that it is not supported, but after that bump mapping works properly. So just test
8265 * if the format is generally supported, and check the BUMPENVMAP flag
8267 IDirect3D9 *d3d9;
8269 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8270 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8271 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8272 L6V5U5_supported = SUCCEEDED(hr);
8273 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8274 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8275 IDirect3D9_Release(d3d9);
8276 if(FAILED(hr)) {
8277 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8278 return;
8282 /* Generate the textures */
8283 generate_bumpmap_textures(device);
8285 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8286 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8288 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8289 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8290 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8291 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8292 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8294 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8295 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8296 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8297 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8298 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8299 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8301 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8302 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8303 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8304 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8305 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8306 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8308 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8309 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8311 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8312 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8315 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8318 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8319 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8320 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8321 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8323 hr = IDirect3DDevice9_BeginScene(device);
8324 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8329 hr = IDirect3DDevice9_EndScene(device);
8330 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8332 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8333 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8334 * But since testing the color match is not the purpose of the test don't be too picky
8336 color = getPixelColor(device, 320-32, 240);
8337 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8338 color = getPixelColor(device, 320+32, 240);
8339 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8340 color = getPixelColor(device, 320, 240-32);
8341 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8342 color = getPixelColor(device, 320, 240+32);
8343 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8344 color = getPixelColor(device, 320, 240);
8345 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8346 color = getPixelColor(device, 320+32, 240+32);
8347 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8348 color = getPixelColor(device, 320-32, 240+32);
8349 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8350 color = getPixelColor(device, 320+32, 240-32);
8351 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8352 color = getPixelColor(device, 320-32, 240-32);
8353 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8354 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8355 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8357 for(i = 0; i < 2; i++) {
8358 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8359 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8360 IDirect3DTexture9_Release(texture); /* For the GetTexture */
8361 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8362 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8363 IDirect3DTexture9_Release(texture); /* To destroy it */
8366 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8367 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8368 goto cleanup;
8370 if(L6V5U5_supported == FALSE) {
8371 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8372 goto cleanup;
8375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8377 /* This test only tests the luminance part. The bumpmapping part was already tested above and
8378 * would only make this test more complicated
8380 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8381 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8382 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8383 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8385 memset(&locked_rect, 0, sizeof(locked_rect));
8386 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8387 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8388 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8389 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8390 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8392 memset(&locked_rect, 0, sizeof(locked_rect));
8393 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8394 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8395 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8396 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8397 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8399 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8400 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8401 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8402 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8404 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8405 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8406 scale = 2.0;
8407 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8408 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8409 offset = 0.1;
8410 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8411 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8413 hr = IDirect3DDevice9_BeginScene(device);
8414 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8415 if(SUCCEEDED(hr)) {
8416 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8417 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8418 hr = IDirect3DDevice9_EndScene(device);
8419 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8422 color = getPixelColor(device, 320, 240);
8423 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
8424 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
8425 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8427 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8428 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8429 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8431 /* Check a result scale factor > 1.0 */
8432 scale = 10;
8433 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8434 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8435 offset = 10;
8436 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8437 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8439 hr = IDirect3DDevice9_BeginScene(device);
8440 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8441 if(SUCCEEDED(hr)) {
8442 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8443 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8444 hr = IDirect3DDevice9_EndScene(device);
8445 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8447 color = getPixelColor(device, 320, 240);
8448 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8449 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8450 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8452 /* Check clamping in the scale factor calculation */
8453 scale = 1000;
8454 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8455 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8456 offset = -1;
8457 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8458 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8460 hr = IDirect3DDevice9_BeginScene(device);
8461 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8462 if(SUCCEEDED(hr)) {
8463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8464 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8465 hr = IDirect3DDevice9_EndScene(device);
8466 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8468 color = getPixelColor(device, 320, 240);
8469 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8470 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8471 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8473 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8474 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8475 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8476 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8478 IDirect3DTexture9_Release(tex1);
8479 IDirect3DTexture9_Release(tex2);
8481 cleanup:
8482 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8483 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8484 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8485 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8487 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8488 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8489 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8492 static void stencil_cull_test(IDirect3DDevice9 *device) {
8493 HRESULT hr;
8494 IDirect3DSurface9 *depthstencil = NULL;
8495 D3DSURFACE_DESC desc;
8496 float quad1[] = {
8497 -1.0, -1.0, 0.1,
8498 0.0, -1.0, 0.1,
8499 -1.0, 0.0, 0.1,
8500 0.0, 0.0, 0.1,
8502 float quad2[] = {
8503 0.0, -1.0, 0.1,
8504 1.0, -1.0, 0.1,
8505 0.0, 0.0, 0.1,
8506 1.0, 0.0, 0.1,
8508 float quad3[] = {
8509 0.0, 0.0, 0.1,
8510 1.0, 0.0, 0.1,
8511 0.0, 1.0, 0.1,
8512 1.0, 1.0, 0.1,
8514 float quad4[] = {
8515 -1.0, 0.0, 0.1,
8516 0.0, 0.0, 0.1,
8517 -1.0, 1.0, 0.1,
8518 0.0, 1.0, 0.1,
8520 struct vertex painter[] = {
8521 {-1.0, -1.0, 0.0, 0x00000000},
8522 { 1.0, -1.0, 0.0, 0x00000000},
8523 {-1.0, 1.0, 0.0, 0x00000000},
8524 { 1.0, 1.0, 0.0, 0x00000000},
8526 WORD indices_cw[] = {0, 1, 3};
8527 WORD indices_ccw[] = {0, 2, 3};
8528 unsigned int i;
8529 DWORD color;
8531 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8532 if(depthstencil == NULL) {
8533 skip("No depth stencil buffer\n");
8534 return;
8536 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8537 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8538 IDirect3DSurface9_Release(depthstencil);
8539 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8540 skip("No 4 or 8 bit stencil surface\n");
8541 return;
8544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8545 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8546 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8547 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8550 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8552 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8554 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8556 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8561 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8563 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8566 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8568 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8570 /* First pass: Fill the stencil buffer with some values... */
8571 hr = IDirect3DDevice9_BeginScene(device);
8572 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8573 if(SUCCEEDED(hr))
8575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8577 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8578 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8579 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8580 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8581 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8582 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8585 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8586 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8587 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8588 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8589 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8590 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8591 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8592 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8593 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8596 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8597 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8598 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8599 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8600 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8601 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8602 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8605 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8606 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8607 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8608 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8609 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8610 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8611 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8613 hr = IDirect3DDevice9_EndScene(device);
8614 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8618 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8621 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8622 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8624 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8628 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8630 /* 2nd pass: Make the stencil values visible */
8631 hr = IDirect3DDevice9_BeginScene(device);
8632 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8633 if(SUCCEEDED(hr))
8635 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8636 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8637 for (i = 0; i < 16; ++i)
8639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8640 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8642 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8643 painter[1].diffuse = (i * 16);
8644 painter[2].diffuse = (i * 16);
8645 painter[3].diffuse = (i * 16);
8646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8647 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8649 hr = IDirect3DDevice9_EndScene(device);
8650 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8654 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8656 color = getPixelColor(device, 160, 420);
8657 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8658 color = getPixelColor(device, 160, 300);
8659 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8661 color = getPixelColor(device, 480, 420);
8662 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8663 color = getPixelColor(device, 480, 300);
8664 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8666 color = getPixelColor(device, 160, 180);
8667 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8668 color = getPixelColor(device, 160, 60);
8669 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8671 color = getPixelColor(device, 480, 180);
8672 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8673 color = getPixelColor(device, 480, 60);
8674 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8676 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8677 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8680 static void vpos_register_test(IDirect3DDevice9 *device)
8682 HRESULT hr;
8683 DWORD color;
8684 const DWORD shader_code[] = {
8685 0xffff0300, /* ps_3_0 */
8686 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8687 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8688 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8689 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8690 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8691 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8692 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8693 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8694 0x0000ffff /* end */
8696 const DWORD shader_frac_code[] = {
8697 0xffff0300, /* ps_3_0 */
8698 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8699 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8700 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8701 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8702 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8703 0x0000ffff /* end */
8705 const DWORD vshader_code[] = {
8706 0xfffe0300, /* vs_3_0 */
8707 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8708 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8709 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8710 0x0000ffff /* end */
8712 IDirect3DVertexShader9 *vshader;
8713 IDirect3DPixelShader9 *shader, *shader_frac;
8714 IDirect3DSurface9 *surface = NULL, *backbuffer;
8715 const float quad[] = {
8716 -1.0, -1.0, 0.1, 0.0, 0.0,
8717 1.0, -1.0, 0.1, 1.0, 0.0,
8718 -1.0, 1.0, 0.1, 0.0, 1.0,
8719 1.0, 1.0, 0.1, 1.0, 1.0,
8721 D3DLOCKED_RECT lr;
8722 float constant[4] = {1.0, 0.0, 320, 240};
8723 DWORD *pos;
8725 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8726 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8727 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8728 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8729 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8730 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8731 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8732 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8733 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8734 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8735 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8736 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8738 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8739 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8740 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8742 hr = IDirect3DDevice9_BeginScene(device);
8743 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8744 if(SUCCEEDED(hr)) {
8745 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8746 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8748 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8749 hr = IDirect3DDevice9_EndScene(device);
8750 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8753 /* This has to be pixel exact */
8754 color = getPixelColor(device, 319, 239);
8755 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8756 color = getPixelColor(device, 320, 239);
8757 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8758 color = getPixelColor(device, 319, 240);
8759 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8760 color = getPixelColor(device, 320, 240);
8761 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8762 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8764 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8765 &surface, NULL);
8766 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8767 hr = IDirect3DDevice9_BeginScene(device);
8768 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8769 if(SUCCEEDED(hr)) {
8770 constant[2] = 16; constant[3] = 16;
8771 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8772 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8773 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8774 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8776 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8777 hr = IDirect3DDevice9_EndScene(device);
8778 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8780 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8781 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8783 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8784 color = *pos & 0x00ffffff;
8785 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8786 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8787 color = *pos & 0x00ffffff;
8788 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8789 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8790 color = *pos & 0x00ffffff;
8791 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8792 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8793 color = *pos & 0x00ffffff;
8794 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8796 hr = IDirect3DSurface9_UnlockRect(surface);
8797 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8799 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8800 * have full control over the multisampling setting inside this test
8802 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8803 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8804 hr = IDirect3DDevice9_BeginScene(device);
8805 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8806 if(SUCCEEDED(hr)) {
8807 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8808 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8810 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8811 hr = IDirect3DDevice9_EndScene(device);
8812 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8814 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8817 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8818 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8820 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8821 color = *pos & 0x00ffffff;
8822 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8824 hr = IDirect3DSurface9_UnlockRect(surface);
8825 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8827 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8828 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8829 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8830 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8831 IDirect3DPixelShader9_Release(shader);
8832 IDirect3DPixelShader9_Release(shader_frac);
8833 IDirect3DVertexShader9_Release(vshader);
8834 if(surface) IDirect3DSurface9_Release(surface);
8835 IDirect3DSurface9_Release(backbuffer);
8838 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8840 D3DCOLOR color;
8842 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8843 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8844 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8845 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8846 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8848 ++r;
8849 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8850 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8851 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8852 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8853 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8855 return TRUE;
8858 static void pointsize_test(IDirect3DDevice9 *device)
8860 HRESULT hr;
8861 D3DCAPS9 caps;
8862 D3DMATRIX matrix;
8863 D3DMATRIX identity;
8864 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8865 DWORD color;
8866 IDirect3DSurface9 *rt, *backbuffer;
8867 IDirect3DTexture9 *tex1, *tex2;
8868 RECT rect = {0, 0, 128, 128};
8869 D3DLOCKED_RECT lr;
8870 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8871 0x00000000, 0x00000000};
8872 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8873 0x00000000, 0x0000ff00};
8875 const float vertices[] = {
8876 64, 64, 0.1,
8877 128, 64, 0.1,
8878 192, 64, 0.1,
8879 256, 64, 0.1,
8880 320, 64, 0.1,
8881 384, 64, 0.1,
8882 448, 64, 0.1,
8883 512, 64, 0.1,
8886 /* 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 */
8887 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;
8888 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;
8889 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;
8890 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;
8892 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;
8893 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;
8894 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;
8895 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;
8897 memset(&caps, 0, sizeof(caps));
8898 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8899 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8900 if(caps.MaxPointSize < 32.0) {
8901 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8902 return;
8905 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8906 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8907 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8908 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8909 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8910 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8911 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8912 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8914 hr = IDirect3DDevice9_BeginScene(device);
8915 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8916 if (SUCCEEDED(hr))
8918 ptsize = 15.0;
8919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8920 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8921 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8922 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8924 ptsize = 31.0;
8925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8926 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8930 ptsize = 30.75;
8931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8932 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8933 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8934 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8936 if (caps.MaxPointSize >= 63.0)
8938 ptsize = 63.0;
8939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8940 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8942 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8944 ptsize = 62.75;
8945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8946 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8948 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8951 ptsize = 1.0;
8952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8953 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8955 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8957 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8958 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8959 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8960 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8962 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8963 ptsize = 15.0;
8964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8965 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8966 ptsize = 1.0;
8967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8968 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8970 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8973 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8975 /* pointsize < pointsize_min < pointsize_max?
8976 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8977 ptsize = 1.0;
8978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8979 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8980 ptsize = 15.0;
8981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8982 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8984 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8989 hr = IDirect3DDevice9_EndScene(device);
8990 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8993 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8994 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8995 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8997 if (caps.MaxPointSize >= 63.0)
8999 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9000 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9003 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9004 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9005 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9006 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9007 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9009 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9011 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9012 * generates texture coordinates for the point(result: Yes, it does)
9014 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9015 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9016 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9019 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9021 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9022 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9023 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9025 memset(&lr, 0, sizeof(lr));
9026 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9027 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9028 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9029 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9030 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9031 memset(&lr, 0, sizeof(lr));
9032 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9033 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9034 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9035 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9036 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9037 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9038 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9039 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9041 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9042 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9043 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9045 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9047 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9049 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9050 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9053 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9054 ptsize = 32.0;
9055 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9056 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9058 hr = IDirect3DDevice9_BeginScene(device);
9059 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9060 if(SUCCEEDED(hr))
9062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9063 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9064 hr = IDirect3DDevice9_EndScene(device);
9065 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9068 color = getPixelColor(device, 64-4, 64-4);
9069 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9070 color = getPixelColor(device, 64-4, 64+4);
9071 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9072 color = getPixelColor(device, 64+4, 64+4);
9073 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9074 color = getPixelColor(device, 64+4, 64-4);
9075 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9076 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9078 U(matrix).m[0][0] = 1.0f / 64.0f;
9079 U(matrix).m[1][1] = -1.0f / 64.0f;
9080 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9081 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9083 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9084 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9086 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9087 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9088 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9090 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9091 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9092 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9093 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9095 hr = IDirect3DDevice9_BeginScene(device);
9096 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9097 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9098 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9099 hr = IDirect3DDevice9_EndScene(device);
9100 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9102 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9103 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9104 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9105 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9106 IDirect3DSurface9_Release(backbuffer);
9107 IDirect3DSurface9_Release(rt);
9109 color = getPixelColor(device, 64-4, 64-4);
9110 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9111 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9112 color = getPixelColor(device, 64+4, 64-4);
9113 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9114 "Expected color 0x00ffff00, got 0x%08x.\n", color);
9115 color = getPixelColor(device, 64-4, 64+4);
9116 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9117 "Expected color 0x00000000, got 0x%08x.\n", color);
9118 color = getPixelColor(device, 64+4, 64+4);
9119 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9120 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9122 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9123 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9125 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9126 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9127 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9128 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9129 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9130 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9131 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9132 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9133 IDirect3DTexture9_Release(tex1);
9134 IDirect3DTexture9_Release(tex2);
9136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9137 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9140 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9141 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9144 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9146 static const DWORD vshader_code[] =
9148 0xfffe0300, /* vs_3_0 */
9149 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9150 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9151 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9152 0x0000ffff /* end */
9154 static const DWORD pshader_code1[] =
9156 0xffff0300, /* ps_3_0 */
9157 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9158 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9159 0x0000ffff /* end */
9161 static const DWORD pshader_code2[] =
9163 0xffff0300, /* ps_3_0 */
9164 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9165 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9166 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9167 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9168 0x0000ffff /* end */
9171 HRESULT hr;
9172 IDirect3DVertexShader9 *vs;
9173 IDirect3DPixelShader9 *ps1, *ps2;
9174 IDirect3DTexture9 *tex1, *tex2;
9175 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9176 D3DCAPS9 caps;
9177 DWORD color;
9178 UINT i, j;
9179 float quad[] = {
9180 -1.0, -1.0, 0.1,
9181 1.0, -1.0, 0.1,
9182 -1.0, 1.0, 0.1,
9183 1.0, 1.0, 0.1,
9185 float texquad[] = {
9186 -1.0, -1.0, 0.1, 0.0, 0.0,
9187 0.0, -1.0, 0.1, 1.0, 0.0,
9188 -1.0, 1.0, 0.1, 0.0, 1.0,
9189 0.0, 1.0, 0.1, 1.0, 1.0,
9191 0.0, -1.0, 0.1, 0.0, 0.0,
9192 1.0, -1.0, 0.1, 1.0, 0.0,
9193 0.0, 1.0, 0.1, 0.0, 1.0,
9194 1.0, 1.0, 0.1, 1.0, 1.0,
9197 memset(&caps, 0, sizeof(caps));
9198 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9199 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9200 if(caps.NumSimultaneousRTs < 2) {
9201 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9202 return;
9205 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9206 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9208 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9209 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9210 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9212 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9213 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9214 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9215 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9216 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9217 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9218 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9219 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9220 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9221 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9222 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9223 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9225 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9226 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9227 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9228 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9229 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9230 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9232 hr = IDirect3DDevice9_SetVertexShader(device, vs);
9233 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9234 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9235 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9236 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9237 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9238 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9239 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9242 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9243 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9244 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9245 color = getPixelColorFromSurface(readback, 8, 8);
9246 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9247 "Expected color 0x000000ff, got 0x%08x.\n", color);
9248 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9249 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9250 color = getPixelColorFromSurface(readback, 8, 8);
9251 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9252 "Expected color 0x000000ff, got 0x%08x.\n", color);
9254 /* Render targets not written by the pixel shader should be unmodified. */
9255 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9256 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9257 hr = IDirect3DDevice9_BeginScene(device);
9258 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9259 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9260 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9261 hr = IDirect3DDevice9_EndScene(device);
9262 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9263 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9264 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9265 color = getPixelColorFromSurface(readback, 8, 8);
9266 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9267 "Expected color 0xff00ff00, got 0x%08x.\n", color);
9268 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9269 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9270 for (i = 6; i < 10; ++i)
9272 for (j = 6; j < 10; ++j)
9274 color = getPixelColorFromSurface(readback, j, i);
9275 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9276 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9281 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9282 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9283 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9284 color = getPixelColorFromSurface(readback, 8, 8);
9285 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9286 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9287 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9288 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9289 color = getPixelColorFromSurface(readback, 8, 8);
9290 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9291 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9293 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9294 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9296 hr = IDirect3DDevice9_BeginScene(device);
9297 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9298 if(SUCCEEDED(hr)) {
9299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9300 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9302 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9303 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9304 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9305 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9306 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9308 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9310 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9313 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9314 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9315 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9316 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9318 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9319 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9321 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9323 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9324 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9326 hr = IDirect3DDevice9_EndScene(device);
9327 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9330 color = getPixelColor(device, 160, 240);
9331 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9332 color = getPixelColor(device, 480, 240);
9333 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9334 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9336 IDirect3DPixelShader9_Release(ps2);
9337 IDirect3DPixelShader9_Release(ps1);
9338 IDirect3DVertexShader9_Release(vs);
9339 IDirect3DTexture9_Release(tex1);
9340 IDirect3DTexture9_Release(tex2);
9341 IDirect3DSurface9_Release(surf1);
9342 IDirect3DSurface9_Release(surf2);
9343 IDirect3DSurface9_Release(backbuf);
9344 IDirect3DSurface9_Release(readback);
9347 struct formats {
9348 const char *fmtName;
9349 D3DFORMAT textureFormat;
9350 DWORD resultColorBlending;
9351 DWORD resultColorNoBlending;
9354 static const struct formats test_formats[] = {
9355 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9356 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9357 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9358 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9359 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9360 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9361 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9362 { NULL, 0 }
9365 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9367 HRESULT hr;
9368 IDirect3DTexture9 *offscreenTexture = NULL;
9369 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9370 IDirect3D9 *d3d = NULL;
9371 DWORD color;
9372 DWORD r0, g0, b0, r1, g1, b1;
9373 int fmt_index;
9375 static const float quad[][5] = {
9376 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9377 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
9378 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9379 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
9382 /* Quad with R=0x10, G=0x20 */
9383 static const struct vertex quad1[] = {
9384 {-1.0f, -1.0f, 0.1f, 0x80102000},
9385 {-1.0f, 1.0f, 0.1f, 0x80102000},
9386 { 1.0f, -1.0f, 0.1f, 0x80102000},
9387 { 1.0f, 1.0f, 0.1f, 0x80102000},
9390 /* Quad with R=0x20, G=0x10 */
9391 static const struct vertex quad2[] = {
9392 {-1.0f, -1.0f, 0.1f, 0x80201000},
9393 {-1.0f, 1.0f, 0.1f, 0x80201000},
9394 { 1.0f, -1.0f, 0.1f, 0x80201000},
9395 { 1.0f, 1.0f, 0.1f, 0x80201000},
9398 IDirect3DDevice9_GetDirect3D(device, &d3d);
9400 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9401 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9402 if(!backbuffer) {
9403 goto out;
9406 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9408 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9410 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9411 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9413 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9414 continue;
9417 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9418 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9420 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9421 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9422 if(!offscreenTexture) {
9423 continue;
9426 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9427 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9428 if(!offscreen) {
9429 continue;
9432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9433 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9435 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9436 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9437 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9438 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9439 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9440 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9441 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9442 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9444 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9446 /* Below we will draw two quads with different colors and try to blend them together.
9447 * The result color is compared with the expected outcome.
9449 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9450 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9451 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9452 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9453 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9456 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9458 /* Draw a quad using color 0x0010200 */
9459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9460 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9464 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9466 /* Draw a quad using color 0x0020100 */
9467 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9468 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9470 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9472 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9474 /* We don't want to blend the result on the backbuffer */
9475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9476 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9478 /* Prepare rendering the 'blended' texture quad to the backbuffer */
9479 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9480 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9481 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9482 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9484 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9485 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9487 /* This time with the texture */
9488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9489 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9491 IDirect3DDevice9_EndScene(device);
9494 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9495 /* Compare the color of the center quad with our expectation */
9496 color = getPixelColor(device, 320, 240);
9497 r0 = (color & 0x00ff0000) >> 16;
9498 g0 = (color & 0x0000ff00) >> 8;
9499 b0 = (color & 0x000000ff) >> 0;
9501 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9502 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9503 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9505 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9506 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9507 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9508 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9509 } else {
9510 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9511 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9512 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9513 color = getPixelColor(device, 320, 240);
9514 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);
9516 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9518 IDirect3DDevice9_SetTexture(device, 0, NULL);
9519 if(offscreenTexture) {
9520 IDirect3DTexture9_Release(offscreenTexture);
9522 if(offscreen) {
9523 IDirect3DSurface9_Release(offscreen);
9527 out:
9528 /* restore things */
9529 if(backbuffer) {
9530 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9531 IDirect3DSurface9_Release(backbuffer);
9535 static void tssargtemp_test(IDirect3DDevice9 *device)
9537 HRESULT hr;
9538 DWORD color;
9539 static const struct vertex quad[] = {
9540 {-1.0, -1.0, 0.1, 0x00ff0000},
9541 { 1.0, -1.0, 0.1, 0x00ff0000},
9542 {-1.0, 1.0, 0.1, 0x00ff0000},
9543 { 1.0, 1.0, 0.1, 0x00ff0000}
9545 D3DCAPS9 caps;
9547 memset(&caps, 0, sizeof(caps));
9548 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9549 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9550 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9551 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9552 return;
9555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9556 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9558 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9559 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9560 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9561 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9563 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9564 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9565 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9566 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9567 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9568 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9570 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9571 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9572 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9573 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9574 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9575 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9577 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9581 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9582 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9583 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9585 hr = IDirect3DDevice9_BeginScene(device);
9586 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9587 if(SUCCEEDED(hr)) {
9588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9589 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9590 hr = IDirect3DDevice9_EndScene(device);
9591 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9593 color = getPixelColor(device, 320, 240);
9594 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9595 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9597 /* Set stage 1 back to default */
9598 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9599 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9600 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9601 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9602 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9603 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9604 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9605 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9606 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9607 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9610 struct testdata
9612 DWORD idxVertex; /* number of instances in the first stream */
9613 DWORD idxColor; /* number of instances in the second stream */
9614 DWORD idxInstance; /* should be 1 ?? */
9615 DWORD color1; /* color 1 instance */
9616 DWORD color2; /* color 2 instance */
9617 DWORD color3; /* color 3 instance */
9618 DWORD color4; /* color 4 instance */
9619 WORD strVertex; /* specify which stream to use 0-2*/
9620 WORD strColor;
9621 WORD strInstance;
9624 static const struct testdata testcases[]=
9626 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9627 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9628 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9629 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9630 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9631 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9632 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9633 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9634 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9635 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9636 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9637 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9638 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9639 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9641 This draws one instance on some machines, no instance on others
9642 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9645 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9646 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9650 /* Drawing Indexed Geometry with instances*/
9651 static void stream_test(IDirect3DDevice9 *device)
9653 IDirect3DVertexBuffer9 *vb = NULL;
9654 IDirect3DVertexBuffer9 *vb2 = NULL;
9655 IDirect3DVertexBuffer9 *vb3 = NULL;
9656 IDirect3DIndexBuffer9 *ib = NULL;
9657 IDirect3DVertexDeclaration9 *pDecl = NULL;
9658 IDirect3DVertexShader9 *shader = NULL;
9659 HRESULT hr;
9660 BYTE *data;
9661 DWORD color;
9662 DWORD ind;
9663 unsigned i;
9665 const DWORD shader_code[] =
9667 0xfffe0101, /* vs_1_1 */
9668 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9669 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9670 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9671 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9672 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9673 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9674 0x0000ffff
9677 const float quad[][3] =
9679 {-0.5f, -0.5f, 1.1f}, /*0 */
9680 {-0.5f, 0.5f, 1.1f}, /*1 */
9681 { 0.5f, -0.5f, 1.1f}, /*2 */
9682 { 0.5f, 0.5f, 1.1f}, /*3 */
9685 const float vertcolor[][4] =
9687 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9688 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9689 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9690 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9693 /* 4 position for 4 instances */
9694 const float instancepos[][3] =
9696 {-0.6f,-0.6f, 0.0f},
9697 { 0.6f,-0.6f, 0.0f},
9698 { 0.6f, 0.6f, 0.0f},
9699 {-0.6f, 0.6f, 0.0f},
9702 short indices[] = {0, 1, 2, 1, 2, 3};
9704 D3DVERTEXELEMENT9 decl[] =
9706 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9707 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9708 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9709 D3DDECL_END()
9712 /* set the default value because it isn't done in wine? */
9713 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9714 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9716 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9717 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9718 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9720 /* check wrong cases */
9721 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9722 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9723 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9724 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9725 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9726 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9727 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9728 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9729 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9730 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9731 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9732 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9733 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9734 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9735 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9736 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9737 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9738 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9739 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9740 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9742 /* set the default value back */
9743 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9744 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9746 /* create all VertexBuffers*/
9747 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9748 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9749 if(!vb) {
9750 skip("Failed to create a vertex buffer\n");
9751 return;
9753 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9754 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9755 if(!vb2) {
9756 skip("Failed to create a vertex buffer\n");
9757 goto out;
9759 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9760 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9761 if(!vb3) {
9762 skip("Failed to create a vertex buffer\n");
9763 goto out;
9766 /* create IndexBuffer*/
9767 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9768 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9769 if(!ib) {
9770 skip("Failed to create a index buffer\n");
9771 goto out;
9774 /* copy all Buffers (Vertex + Index)*/
9775 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9776 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9777 memcpy(data, quad, sizeof(quad));
9778 hr = IDirect3DVertexBuffer9_Unlock(vb);
9779 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9780 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9781 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9782 memcpy(data, vertcolor, sizeof(vertcolor));
9783 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9784 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9785 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9786 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9787 memcpy(data, instancepos, sizeof(instancepos));
9788 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9789 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9790 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9791 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9792 memcpy(data, indices, sizeof(indices));
9793 hr = IDirect3DIndexBuffer9_Unlock(ib);
9794 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9796 /* create VertexShader */
9797 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9798 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9799 if(!shader) {
9800 skip("Failed to create a vetex shader\n");
9801 goto out;
9804 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9805 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9807 hr = IDirect3DDevice9_SetIndices(device, ib);
9808 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9810 /* run all tests */
9811 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9813 struct testdata act = testcases[i];
9814 decl[0].Stream = act.strVertex;
9815 decl[1].Stream = act.strColor;
9816 decl[2].Stream = act.strInstance;
9817 /* create VertexDeclarations */
9818 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9819 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9821 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9822 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9824 hr = IDirect3DDevice9_BeginScene(device);
9825 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9826 if(SUCCEEDED(hr))
9828 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9829 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9831 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9832 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9833 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9834 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9836 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9837 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9838 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9839 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9841 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9842 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9843 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9844 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9846 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9847 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9848 hr = IDirect3DDevice9_EndScene(device);
9849 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9851 /* set all StreamSource && StreamSourceFreq back to default */
9852 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9853 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9854 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9855 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9856 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9857 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9858 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9859 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9860 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9861 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9862 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9863 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9866 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9867 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9869 color = getPixelColor(device, 160, 360);
9870 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9871 color = getPixelColor(device, 480, 360);
9872 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9873 color = getPixelColor(device, 480, 120);
9874 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9875 color = getPixelColor(device, 160, 120);
9876 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9879 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9882 hr = IDirect3DDevice9_SetIndices(device, NULL);
9883 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9885 out:
9886 if(vb) IDirect3DVertexBuffer9_Release(vb);
9887 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9888 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9889 if(ib)IDirect3DIndexBuffer9_Release(ib);
9890 if(shader)IDirect3DVertexShader9_Release(shader);
9893 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9894 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9895 IDirect3DTexture9 *dsttex = NULL;
9896 HRESULT hr;
9897 DWORD color;
9898 D3DRECT r1 = {0, 0, 50, 50 };
9899 D3DRECT r2 = {50, 0, 100, 50 };
9900 D3DRECT r3 = {50, 50, 100, 100};
9901 D3DRECT r4 = {0, 50, 50, 100};
9902 const float quad[] = {
9903 -1.0, -1.0, 0.1, 0.0, 0.0,
9904 1.0, -1.0, 0.1, 1.0, 0.0,
9905 -1.0, 1.0, 0.1, 0.0, 1.0,
9906 1.0, 1.0, 0.1, 1.0, 1.0,
9909 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9910 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9912 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9913 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9914 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9915 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9917 if(!src || !dsttex) {
9918 skip("One or more test resources could not be created\n");
9919 goto cleanup;
9922 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9923 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9926 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9928 /* Clear the StretchRect destination for debugging */
9929 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9930 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9932 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9935 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9937 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9938 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9939 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9940 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9941 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9942 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9943 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9944 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9946 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9947 * the target -> texture GL blit path
9949 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9950 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9951 IDirect3DSurface9_Release(dst);
9953 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9954 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9956 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9957 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9958 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9959 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9960 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9961 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9962 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9963 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9965 hr = IDirect3DDevice9_BeginScene(device);
9966 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9967 if(SUCCEEDED(hr)) {
9968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9970 hr = IDirect3DDevice9_EndScene(device);
9971 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9974 color = getPixelColor(device, 160, 360);
9975 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9976 color = getPixelColor(device, 480, 360);
9977 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9978 color = getPixelColor(device, 480, 120);
9979 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9980 color = getPixelColor(device, 160, 120);
9981 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9982 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9983 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9985 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9986 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9987 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9988 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9990 cleanup:
9991 if(src) IDirect3DSurface9_Release(src);
9992 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9993 if(dsttex) IDirect3DTexture9_Release(dsttex);
9996 static void texop_test(IDirect3DDevice9 *device)
9998 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9999 IDirect3DTexture9 *texture = NULL;
10000 D3DLOCKED_RECT locked_rect;
10001 D3DCOLOR color;
10002 D3DCAPS9 caps;
10003 HRESULT hr;
10004 unsigned i;
10006 static const struct {
10007 float x, y, z;
10008 float s, t;
10009 D3DCOLOR diffuse;
10010 } quad[] = {
10011 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10012 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10013 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10014 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10017 static const D3DVERTEXELEMENT9 decl_elements[] = {
10018 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10019 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10020 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10021 D3DDECL_END()
10024 static const struct {
10025 D3DTEXTUREOP op;
10026 const char *name;
10027 DWORD caps_flag;
10028 D3DCOLOR result;
10029 } test_data[] = {
10030 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10031 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10032 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10033 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10034 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10035 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10036 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10037 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10038 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10039 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10040 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10041 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10042 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10043 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10044 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10045 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10046 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10047 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10048 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10049 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10050 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10051 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10052 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10055 memset(&caps, 0, sizeof(caps));
10056 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10057 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10059 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10060 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10061 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10062 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10064 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10065 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10066 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10067 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10068 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10069 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10070 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10071 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10072 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10074 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10075 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10076 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10077 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10078 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10079 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10081 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10082 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10085 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10087 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10089 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10091 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10092 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10094 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10096 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10098 skip("tex operation %s not supported\n", test_data[i].name);
10099 continue;
10102 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10103 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10105 hr = IDirect3DDevice9_BeginScene(device);
10106 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10109 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10111 hr = IDirect3DDevice9_EndScene(device);
10112 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10114 color = getPixelColor(device, 320, 240);
10115 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10116 test_data[i].name, color, test_data[i].result);
10118 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10119 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10122 if (texture) IDirect3DTexture9_Release(texture);
10123 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10126 static void yuv_color_test(IDirect3DDevice9 *device) {
10127 HRESULT hr;
10128 IDirect3DSurface9 *surface = NULL, *target = NULL;
10129 unsigned int fmt, i;
10130 D3DFORMAT format;
10131 const char *fmt_string;
10132 D3DLOCKED_RECT lr;
10133 IDirect3D9 *d3d;
10134 HRESULT color;
10135 DWORD ref_color_left, ref_color_right;
10137 struct {
10138 DWORD in; /* The input color */
10139 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10140 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10141 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10142 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10143 } test_data[] = {
10144 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10145 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10146 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10147 * that
10149 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10150 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10151 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10152 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10153 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10154 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10155 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10156 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10157 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10158 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10159 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10160 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10161 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10162 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10164 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10165 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10166 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10167 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10170 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10171 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10172 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10173 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10175 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10176 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10178 for(fmt = 0; fmt < 2; fmt++) {
10179 if(fmt == 0) {
10180 format = D3DFMT_UYVY;
10181 fmt_string = "D3DFMT_UYVY";
10182 } else {
10183 format = D3DFMT_YUY2;
10184 fmt_string = "D3DFMT_YUY2";
10187 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10188 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10190 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10191 D3DRTYPE_SURFACE, format) != D3D_OK) {
10192 skip("%s is not supported\n", fmt_string);
10193 continue;
10196 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10197 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10200 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10201 if(fmt == 0) {
10202 ref_color_left = test_data[i].uyvy_left;
10203 ref_color_right = test_data[i].uyvy_right;
10204 } else {
10205 ref_color_left = test_data[i].yuy2_left;
10206 ref_color_right = test_data[i].yuy2_right;
10209 memset(&lr, 0, sizeof(lr));
10210 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10211 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10212 *((DWORD *) lr.pBits) = test_data[i].in;
10213 hr = IDirect3DSurface9_UnlockRect(surface);
10214 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10216 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10217 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10218 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10219 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10221 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10222 * prevent running into precision problems, read a far left and far right pixel. In the future we may
10223 * want to add tests for the filtered pixels as well.
10225 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10226 * differently, so we need a max diff of 16
10228 color = getPixelColor(device, 40, 240);
10230 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10231 * where U != V. Skip the entire test if this bug in this case
10233 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10235 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10236 IDirect3DSurface9_Release(surface);
10237 goto out;
10240 ok(color_match(color, ref_color_left, 18),
10241 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10242 test_data[i].in, color, ref_color_left, fmt_string);
10243 color = getPixelColor(device, 600, 240);
10244 ok(color_match(color, ref_color_right, 18),
10245 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10246 test_data[i].in, color, ref_color_right, fmt_string);
10247 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10248 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10250 IDirect3DSurface9_Release(surface);
10253 out:
10254 IDirect3DSurface9_Release(target);
10255 IDirect3D9_Release(d3d);
10258 static void texop_range_test(IDirect3DDevice9 *device)
10260 static const struct {
10261 float x, y, z;
10262 D3DCOLOR diffuse;
10263 } quad[] = {
10264 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10265 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10266 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10267 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10269 HRESULT hr;
10270 IDirect3DTexture9 *texture;
10271 D3DLOCKED_RECT locked_rect;
10272 D3DCAPS9 caps;
10273 DWORD color;
10275 /* We need ADD and SUBTRACT operations */
10276 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10277 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10278 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10279 skip("D3DTOP_ADD is not supported, skipping value range test\n");
10280 return;
10282 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10283 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10284 return;
10287 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10288 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10289 /* Stage 1: result = diffuse(=1.0) + diffuse
10290 * stage 2: result = result - tfactor(= 0.5)
10292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10293 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10294 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10295 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10296 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10297 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10298 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10299 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10300 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10301 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10302 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10303 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10304 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10305 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10307 hr = IDirect3DDevice9_BeginScene(device);
10308 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10310 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10311 hr = IDirect3DDevice9_EndScene(device);
10312 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10314 color = getPixelColor(device, 320, 240);
10315 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10316 color);
10317 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10318 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10320 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10321 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10322 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10323 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10324 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10325 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10326 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10327 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10328 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10330 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10331 * stage 2: result = result + diffuse(1.0)
10333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10334 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10335 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10336 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10337 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10338 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10339 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10340 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10341 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10342 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10343 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10344 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10345 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10346 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10348 hr = IDirect3DDevice9_BeginScene(device);
10349 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10352 hr = IDirect3DDevice9_EndScene(device);
10353 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10355 color = getPixelColor(device, 320, 240);
10356 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10357 color);
10358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10359 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10361 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10362 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10363 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10364 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10365 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10366 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10367 IDirect3DTexture9_Release(texture);
10370 static void alphareplicate_test(IDirect3DDevice9 *device) {
10371 struct vertex quad[] = {
10372 { -1.0, -1.0, 0.1, 0x80ff00ff },
10373 { 1.0, -1.0, 0.1, 0x80ff00ff },
10374 { -1.0, 1.0, 0.1, 0x80ff00ff },
10375 { 1.0, 1.0, 0.1, 0x80ff00ff },
10377 HRESULT hr;
10378 DWORD color;
10380 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10381 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10383 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10384 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10386 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10387 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10388 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10389 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10391 hr = IDirect3DDevice9_BeginScene(device);
10392 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10393 if(SUCCEEDED(hr)) {
10394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10395 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10396 hr = IDirect3DDevice9_EndScene(device);
10397 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10400 color = getPixelColor(device, 320, 240);
10401 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10402 color);
10403 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10404 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10406 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10407 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10411 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10412 HRESULT hr;
10413 D3DCAPS9 caps;
10414 DWORD color;
10415 struct vertex quad[] = {
10416 { -1.0, -1.0, 0.1, 0x408080c0 },
10417 { 1.0, -1.0, 0.1, 0x408080c0 },
10418 { -1.0, 1.0, 0.1, 0x408080c0 },
10419 { 1.0, 1.0, 0.1, 0x408080c0 },
10422 memset(&caps, 0, sizeof(caps));
10423 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10424 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10425 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10426 skip("D3DTOP_DOTPRODUCT3 not supported\n");
10427 return;
10430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10431 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10433 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10434 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10436 /* dp3_x4 r0, diffuse_bias, tfactor_bias
10437 * mov r0.a, diffuse.a
10438 * mov r0, r0.a
10440 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10441 * 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
10442 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10444 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10445 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10446 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10447 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10448 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10449 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10450 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10451 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10452 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10453 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10454 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10455 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10456 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10457 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10458 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10459 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10461 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10463 hr = IDirect3DDevice9_BeginScene(device);
10464 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10465 if(SUCCEEDED(hr)) {
10466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10467 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10468 hr = IDirect3DDevice9_EndScene(device);
10469 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10472 color = getPixelColor(device, 320, 240);
10473 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10474 color);
10475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10476 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10478 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10479 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10480 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10481 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10482 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10483 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10486 static void zwriteenable_test(IDirect3DDevice9 *device) {
10487 HRESULT hr;
10488 DWORD color;
10489 struct vertex quad1[] = {
10490 { -1.0, -1.0, 0.1, 0x00ff0000},
10491 { -1.0, 1.0, 0.1, 0x00ff0000},
10492 { 1.0, -1.0, 0.1, 0x00ff0000},
10493 { 1.0, 1.0, 0.1, 0x00ff0000},
10495 struct vertex quad2[] = {
10496 { -1.0, -1.0, 0.9, 0x0000ff00},
10497 { -1.0, 1.0, 0.9, 0x0000ff00},
10498 { 1.0, -1.0, 0.9, 0x0000ff00},
10499 { 1.0, 1.0, 0.9, 0x0000ff00},
10502 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10503 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10505 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10506 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10508 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10510 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10512 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10514 hr = IDirect3DDevice9_BeginScene(device);
10515 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10516 if(SUCCEEDED(hr)) {
10517 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10518 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10519 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10520 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10521 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10522 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10525 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10529 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10531 hr = IDirect3DDevice9_EndScene(device);
10532 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10535 color = getPixelColor(device, 320, 240);
10536 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10537 color);
10538 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10539 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10542 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10545 static void alphatest_test(IDirect3DDevice9 *device) {
10546 #define ALPHATEST_PASSED 0x0000ff00
10547 #define ALPHATEST_FAILED 0x00ff0000
10548 struct {
10549 D3DCMPFUNC func;
10550 DWORD color_less;
10551 DWORD color_equal;
10552 DWORD color_greater;
10553 } testdata[] = {
10554 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10555 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10556 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10557 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10558 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10559 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10560 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10561 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10563 unsigned int i, j;
10564 HRESULT hr;
10565 DWORD color;
10566 struct vertex quad[] = {
10567 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10568 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10569 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10570 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10572 D3DCAPS9 caps;
10574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10576 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10577 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10579 for(j = 0; j < 2; j++) {
10580 if(j == 1) {
10581 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10582 * the alpha test either for performance reasons(floating point RTs) or to work
10583 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10584 * codepath for ffp and shader in this case, and the test should cover both
10586 IDirect3DPixelShader9 *ps;
10587 DWORD shader_code[] = {
10588 0xffff0101, /* ps_1_1 */
10589 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10590 0x0000ffff /* end */
10592 memset(&caps, 0, sizeof(caps));
10593 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10594 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10595 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10596 break;
10599 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10600 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10601 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10602 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10603 IDirect3DPixelShader9_Release(ps);
10606 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10608 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10610 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10611 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10613 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10614 hr = IDirect3DDevice9_BeginScene(device);
10615 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10616 if(SUCCEEDED(hr)) {
10617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10618 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10619 hr = IDirect3DDevice9_EndScene(device);
10620 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10622 color = getPixelColor(device, 320, 240);
10623 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10624 color, testdata[i].color_less, testdata[i].func);
10625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10626 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10629 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10631 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10632 hr = IDirect3DDevice9_BeginScene(device);
10633 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10634 if(SUCCEEDED(hr)) {
10635 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10636 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10637 hr = IDirect3DDevice9_EndScene(device);
10638 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10640 color = getPixelColor(device, 320, 240);
10641 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10642 color, testdata[i].color_equal, testdata[i].func);
10643 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10644 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10647 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10649 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10650 hr = IDirect3DDevice9_BeginScene(device);
10651 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10652 if(SUCCEEDED(hr)) {
10653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10654 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10655 hr = IDirect3DDevice9_EndScene(device);
10656 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10658 color = getPixelColor(device, 320, 240);
10659 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10660 color, testdata[i].color_greater, testdata[i].func);
10661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10662 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10668 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10669 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10672 static void sincos_test(IDirect3DDevice9 *device) {
10673 const DWORD sin_shader_code[] = {
10674 0xfffe0200, /* vs_2_0 */
10675 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10676 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10677 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10678 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10679 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10680 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10681 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10682 0x0000ffff /* end */
10684 const DWORD cos_shader_code[] = {
10685 0xfffe0200, /* vs_2_0 */
10686 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10687 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10688 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10689 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10690 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10691 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10692 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10693 0x0000ffff /* end */
10695 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10696 HRESULT hr;
10697 struct {
10698 float x, y, z;
10699 } data[1280];
10700 unsigned int i;
10701 float sincosc1[4] = {D3DSINCOSCONST1};
10702 float sincosc2[4] = {D3DSINCOSCONST2};
10704 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10705 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10707 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10708 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10709 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10710 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10711 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10712 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10713 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10714 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10715 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10716 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10718 /* Generate a point from -1 to 1 every 0.5 pixels */
10719 for(i = 0; i < 1280; i++) {
10720 data[i].x = (-640.0 + i) / 640.0;
10721 data[i].y = 0.0;
10722 data[i].z = 0.1;
10725 hr = IDirect3DDevice9_BeginScene(device);
10726 if(SUCCEEDED(hr)) {
10727 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10728 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10730 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10732 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10733 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10735 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10737 hr = IDirect3DDevice9_EndScene(device);
10738 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10740 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10741 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10742 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10744 IDirect3DDevice9_SetVertexShader(device, NULL);
10745 IDirect3DVertexShader9_Release(sin_shader);
10746 IDirect3DVertexShader9_Release(cos_shader);
10749 static void loop_index_test(IDirect3DDevice9 *device) {
10750 const DWORD shader_code[] = {
10751 0xfffe0200, /* vs_2_0 */
10752 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10753 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10754 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10755 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10756 0x0000001d, /* endloop */
10757 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10758 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10759 0x0000ffff /* END */
10761 IDirect3DVertexShader9 *shader;
10762 HRESULT hr;
10763 DWORD color;
10764 const float quad[] = {
10765 -1.0, -1.0, 0.1,
10766 1.0, -1.0, 0.1,
10767 -1.0, 1.0, 0.1,
10768 1.0, 1.0, 0.1
10770 const float zero[4] = {0, 0, 0, 0};
10771 const float one[4] = {1, 1, 1, 1};
10772 int i0[4] = {2, 10, -3, 0};
10773 float values[4];
10775 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10776 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10777 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10778 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10779 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10780 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10782 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10784 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10785 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10786 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10787 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10788 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10789 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10790 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10791 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10792 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10793 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10794 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10795 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10796 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10797 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10798 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10799 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10800 values[0] = 1.0;
10801 values[1] = 1.0;
10802 values[2] = 0.0;
10803 values[3] = 0.0;
10804 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10805 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10806 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10807 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10808 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10809 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10810 values[0] = -1.0;
10811 values[1] = 0.0;
10812 values[2] = 0.0;
10813 values[3] = 0.0;
10814 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10815 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10816 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10817 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10818 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10819 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10820 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10821 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10822 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10823 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10825 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10826 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10828 hr = IDirect3DDevice9_BeginScene(device);
10829 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10830 if(SUCCEEDED(hr))
10832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10833 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10834 hr = IDirect3DDevice9_EndScene(device);
10835 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10837 color = getPixelColor(device, 320, 240);
10838 ok(color_match(color, 0x0000ff00, 1),
10839 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10841 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10843 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10844 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10845 IDirect3DVertexShader9_Release(shader);
10848 static void sgn_test(IDirect3DDevice9 *device) {
10849 const DWORD shader_code[] = {
10850 0xfffe0200, /* vs_2_0 */
10851 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10852 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10853 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10854 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10855 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10856 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10857 0x0000ffff /* end */
10859 IDirect3DVertexShader9 *shader;
10860 HRESULT hr;
10861 DWORD color;
10862 const float quad[] = {
10863 -1.0, -1.0, 0.1,
10864 1.0, -1.0, 0.1,
10865 -1.0, 1.0, 0.1,
10866 1.0, 1.0, 0.1
10869 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10870 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10871 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10872 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10874 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10875 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10876 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10878 hr = IDirect3DDevice9_BeginScene(device);
10879 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10880 if(SUCCEEDED(hr))
10882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10883 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10884 hr = IDirect3DDevice9_EndScene(device);
10885 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10887 color = getPixelColor(device, 320, 240);
10888 ok(color_match(color, 0x008000ff, 1),
10889 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10890 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10891 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10893 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10894 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10895 IDirect3DVertexShader9_Release(shader);
10898 static void viewport_test(IDirect3DDevice9 *device) {
10899 HRESULT hr;
10900 DWORD color;
10901 D3DVIEWPORT9 vp, old_vp;
10902 BOOL draw_failed = TRUE;
10903 const float quad[] =
10905 -0.5, -0.5, 0.1,
10906 0.5, -0.5, 0.1,
10907 -0.5, 0.5, 0.1,
10908 0.5, 0.5, 0.1
10911 memset(&old_vp, 0, sizeof(old_vp));
10912 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10913 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10915 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10916 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10918 /* Test a viewport with Width and Height bigger than the surface dimensions
10920 * TODO: Test Width < surface.width, but X + Width > surface.width
10921 * TODO: Test Width < surface.width, what happens with the height?
10923 * The expected behavior is that the viewport behaves like the "default"
10924 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10925 * MinZ = 0.0, MaxZ = 1.0.
10927 * Starting with Windows 7 the behavior among driver versions is not
10928 * consistent. The SetViewport call is accepted on all drivers. Some
10929 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10930 * nvidia drivers draw, but use the actual values in the viewport and only
10931 * display the upper left part on the surface.
10933 memset(&vp, 0, sizeof(vp));
10934 vp.X = 0;
10935 vp.Y = 0;
10936 vp.Width = 10000;
10937 vp.Height = 10000;
10938 vp.MinZ = 0.0;
10939 vp.MaxZ = 0.0;
10940 hr = IDirect3DDevice9_SetViewport(device, &vp);
10941 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10944 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10945 hr = IDirect3DDevice9_BeginScene(device);
10946 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10947 if(SUCCEEDED(hr))
10949 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10950 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10951 draw_failed = FAILED(hr);
10952 hr = IDirect3DDevice9_EndScene(device);
10953 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10956 if(!draw_failed)
10958 color = getPixelColor(device, 158, 118);
10959 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10960 color = getPixelColor(device, 162, 118);
10961 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10962 color = getPixelColor(device, 158, 122);
10963 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10964 color = getPixelColor(device, 162, 122);
10965 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10967 color = getPixelColor(device, 478, 358);
10968 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10969 color = getPixelColor(device, 482, 358);
10970 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10971 color = getPixelColor(device, 478, 362);
10972 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10973 color = getPixelColor(device, 482, 362);
10974 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10978 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10980 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10981 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10984 /* This test tests depth clamping / clipping behaviour:
10985 * - With software vertex processing, depth values are clamped to the
10986 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10987 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10988 * same as regular vertices here.
10989 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10990 * Normal vertices are always clipped. Pretransformed vertices are
10991 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10992 * - The viewport's MinZ/MaxZ is irrelevant for this.
10994 static void depth_clamp_test(IDirect3DDevice9 *device)
10996 const struct tvertex quad1[] =
10998 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10999 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
11000 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
11001 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
11003 const struct tvertex quad2[] =
11005 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11006 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11007 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11008 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11010 const struct tvertex quad3[] =
11012 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
11013 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
11014 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
11015 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
11017 const struct tvertex quad4[] =
11019 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
11020 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
11021 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11022 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11024 const struct vertex quad5[] =
11026 { -0.5f, 0.5f, 10.0f, 0xff14f914},
11027 { 0.5f, 0.5f, 10.0f, 0xff14f914},
11028 { -0.5f, -0.5f, 10.0f, 0xff14f914},
11029 { 0.5f, -0.5f, 10.0f, 0xff14f914},
11031 const struct vertex quad6[] =
11033 { -1.0f, 0.5f, 10.0f, 0xfff91414},
11034 { 1.0f, 0.5f, 10.0f, 0xfff91414},
11035 { -1.0f, 0.25f, 10.0f, 0xfff91414},
11036 { 1.0f, 0.25f, 10.0f, 0xfff91414},
11039 D3DVIEWPORT9 vp;
11040 D3DCOLOR color;
11041 D3DCAPS9 caps;
11042 HRESULT hr;
11044 vp.X = 0;
11045 vp.Y = 0;
11046 vp.Width = 640;
11047 vp.Height = 480;
11048 vp.MinZ = 0.0;
11049 vp.MaxZ = 7.5;
11051 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11052 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11054 hr = IDirect3DDevice9_SetViewport(device, &vp);
11055 if(FAILED(hr))
11057 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11058 * the tests because the 7.5 is just intended to show that it doesn't have
11059 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11060 * viewport and continue.
11062 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11063 vp.MaxZ = 1.0;
11064 hr = IDirect3DDevice9_SetViewport(device, &vp);
11066 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11069 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11072 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11074 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11076 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11078 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11080 hr = IDirect3DDevice9_BeginScene(device);
11081 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11083 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11084 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11087 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11089 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11092 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11094 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11095 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11097 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11099 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11100 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11102 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11103 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11109 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11112 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11114 hr = IDirect3DDevice9_EndScene(device);
11115 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11117 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11119 color = getPixelColor(device, 75, 75);
11120 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11121 color = getPixelColor(device, 150, 150);
11122 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11123 color = getPixelColor(device, 320, 240);
11124 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11125 color = getPixelColor(device, 320, 330);
11126 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11127 color = getPixelColor(device, 320, 330);
11128 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11130 else
11132 color = getPixelColor(device, 75, 75);
11133 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11134 color = getPixelColor(device, 150, 150);
11135 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11136 color = getPixelColor(device, 320, 240);
11137 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11138 color = getPixelColor(device, 320, 330);
11139 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11140 color = getPixelColor(device, 320, 330);
11141 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11145 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11147 vp.MinZ = 0.0;
11148 vp.MaxZ = 1.0;
11149 hr = IDirect3DDevice9_SetViewport(device, &vp);
11150 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11153 static void depth_bounds_test(IDirect3DDevice9 *device)
11155 const struct tvertex quad1[] =
11157 { 0, 0, 0.0f, 1, 0xfff9e814},
11158 { 640, 0, 0.0f, 1, 0xfff9e814},
11159 { 0, 480, 1.0f, 1, 0xfff9e814},
11160 { 640, 480, 1.0f, 1, 0xfff9e814},
11162 const struct tvertex quad2[] =
11164 { 0, 0, 0.6f, 1, 0xff002b7f},
11165 { 640, 0, 0.6f, 1, 0xff002b7f},
11166 { 0, 480, 0.6f, 1, 0xff002b7f},
11167 { 640, 480, 0.6f, 1, 0xff002b7f},
11169 const struct tvertex quad3[] =
11171 { 0, 100, 0.6f, 1, 0xfff91414},
11172 { 640, 100, 0.6f, 1, 0xfff91414},
11173 { 0, 160, 0.6f, 1, 0xfff91414},
11174 { 640, 160, 0.6f, 1, 0xfff91414},
11177 union {
11178 DWORD d;
11179 float f;
11180 } tmpvalue;
11182 IDirect3D9 *d3d = NULL;
11183 IDirect3DSurface9 *offscreen_surface = NULL;
11184 D3DCOLOR color;
11185 HRESULT hr;
11187 IDirect3DDevice9_GetDirect3D(device, &d3d);
11188 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11189 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11190 skip("No NVDB (depth bounds test) support\n");
11191 IDirect3D9_Release(d3d);
11192 return;
11194 IDirect3D9_Release(d3d);
11196 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11197 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11198 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11199 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11202 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11205 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11207 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11209 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11211 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11214 hr = IDirect3DDevice9_BeginScene(device);
11215 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11217 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11218 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11221 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11224 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11226 tmpvalue.f = 0.625;
11227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11228 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11230 tmpvalue.f = 0.75;
11231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11232 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11235 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11237 tmpvalue.f = 0.75;
11238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11241 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11242 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11245 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11247 hr = IDirect3DDevice9_EndScene(device);
11248 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11250 color = getPixelColor(device, 150, 130);
11251 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11252 color = getPixelColor(device, 150, 200);
11253 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11254 color = getPixelColor(device, 150, 300-5);
11255 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11256 color = getPixelColor(device, 150, 300+5);
11257 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11258 color = getPixelColor(device, 150, 330);
11259 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11260 color = getPixelColor(device, 150, 360-5);
11261 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11262 color = getPixelColor(device, 150, 360+5);
11263 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11266 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11269 static void depth_buffer_test(IDirect3DDevice9 *device)
11271 static const struct vertex quad1[] =
11273 { -1.0, 1.0, 0.33f, 0xff00ff00},
11274 { 1.0, 1.0, 0.33f, 0xff00ff00},
11275 { -1.0, -1.0, 0.33f, 0xff00ff00},
11276 { 1.0, -1.0, 0.33f, 0xff00ff00},
11278 static const struct vertex quad2[] =
11280 { -1.0, 1.0, 0.50f, 0xffff00ff},
11281 { 1.0, 1.0, 0.50f, 0xffff00ff},
11282 { -1.0, -1.0, 0.50f, 0xffff00ff},
11283 { 1.0, -1.0, 0.50f, 0xffff00ff},
11285 static const struct vertex quad3[] =
11287 { -1.0, 1.0, 0.66f, 0xffff0000},
11288 { 1.0, 1.0, 0.66f, 0xffff0000},
11289 { -1.0, -1.0, 0.66f, 0xffff0000},
11290 { 1.0, -1.0, 0.66f, 0xffff0000},
11292 static const DWORD expected_colors[4][4] =
11294 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11295 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11296 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11297 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11300 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11301 unsigned int i, j;
11302 D3DVIEWPORT9 vp;
11303 D3DCOLOR color;
11304 HRESULT hr;
11306 vp.X = 0;
11307 vp.Y = 0;
11308 vp.Width = 640;
11309 vp.Height = 480;
11310 vp.MinZ = 0.0;
11311 vp.MaxZ = 1.0;
11313 hr = IDirect3DDevice9_SetViewport(device, &vp);
11314 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11317 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11319 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11321 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11323 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11324 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11325 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11327 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11328 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11329 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11330 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11331 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11332 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11333 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11334 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11335 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11336 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11337 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11339 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11340 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11342 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11344 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11345 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11346 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11347 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11349 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11350 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11351 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11352 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11354 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11355 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11356 hr = IDirect3DDevice9_BeginScene(device);
11357 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11359 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11360 hr = IDirect3DDevice9_EndScene(device);
11361 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11363 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11364 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11365 IDirect3DSurface9_Release(backbuffer);
11366 IDirect3DSurface9_Release(rt3);
11367 IDirect3DSurface9_Release(rt2);
11368 IDirect3DSurface9_Release(rt1);
11370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11371 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11373 hr = IDirect3DDevice9_BeginScene(device);
11374 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11376 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11378 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11379 hr = IDirect3DDevice9_EndScene(device);
11380 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11382 for (i = 0; i < 4; ++i)
11384 for (j = 0; j < 4; ++j)
11386 unsigned int x = 80 * ((2 * j) + 1);
11387 unsigned int y = 60 * ((2 * i) + 1);
11388 color = getPixelColor(device, x, y);
11389 ok(color_match(color, expected_colors[i][j], 0),
11390 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11394 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11395 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11398 /* Test that partial depth copies work the way they're supposed to. The clear
11399 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11400 * the following draw should only copy back the part that was modified. */
11401 static void depth_buffer2_test(IDirect3DDevice9 *device)
11403 static const struct vertex quad[] =
11405 { -1.0, 1.0, 0.66f, 0xffff0000},
11406 { 1.0, 1.0, 0.66f, 0xffff0000},
11407 { -1.0, -1.0, 0.66f, 0xffff0000},
11408 { 1.0, -1.0, 0.66f, 0xffff0000},
11411 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11412 unsigned int i, j;
11413 D3DVIEWPORT9 vp;
11414 D3DCOLOR color;
11415 HRESULT hr;
11417 vp.X = 0;
11418 vp.Y = 0;
11419 vp.Width = 640;
11420 vp.Height = 480;
11421 vp.MinZ = 0.0;
11422 vp.MaxZ = 1.0;
11424 hr = IDirect3DDevice9_SetViewport(device, &vp);
11425 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11427 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11428 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11429 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11430 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11432 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11433 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11434 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11435 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11436 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11438 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11439 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11440 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11441 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11442 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11443 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11444 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11445 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11447 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11448 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11449 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11450 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11452 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11453 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11454 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11455 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11457 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11458 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11459 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11460 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11462 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11463 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11464 IDirect3DSurface9_Release(backbuffer);
11465 IDirect3DSurface9_Release(rt2);
11466 IDirect3DSurface9_Release(rt1);
11468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11469 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11471 hr = IDirect3DDevice9_BeginScene(device);
11472 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11474 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11475 hr = IDirect3DDevice9_EndScene(device);
11476 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11478 for (i = 0; i < 4; ++i)
11480 for (j = 0; j < 4; ++j)
11482 unsigned int x = 80 * ((2 * j) + 1);
11483 unsigned int y = 60 * ((2 * i) + 1);
11484 color = getPixelColor(device, x, y);
11485 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11486 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11490 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11491 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11494 static void depth_blit_test(IDirect3DDevice9 *device)
11496 static const struct vertex quad1[] =
11498 { -1.0, 1.0, 0.50f, 0xff00ff00},
11499 { 1.0, 1.0, 0.50f, 0xff00ff00},
11500 { -1.0, -1.0, 0.50f, 0xff00ff00},
11501 { 1.0, -1.0, 0.50f, 0xff00ff00},
11503 static const struct vertex quad2[] =
11505 { -1.0, 1.0, 0.66f, 0xff0000ff},
11506 { 1.0, 1.0, 0.66f, 0xff0000ff},
11507 { -1.0, -1.0, 0.66f, 0xff0000ff},
11508 { 1.0, -1.0, 0.66f, 0xff0000ff},
11510 static const DWORD expected_colors[4][4] =
11512 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11513 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11514 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11515 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11518 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11519 RECT src_rect, dst_rect;
11520 unsigned int i, j;
11521 D3DVIEWPORT9 vp;
11522 D3DCOLOR color;
11523 HRESULT hr;
11525 vp.X = 0;
11526 vp.Y = 0;
11527 vp.Width = 640;
11528 vp.Height = 480;
11529 vp.MinZ = 0.0;
11530 vp.MaxZ = 1.0;
11532 hr = IDirect3DDevice9_SetViewport(device, &vp);
11533 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11535 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11536 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11537 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11538 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11539 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11540 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11541 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11542 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11543 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11544 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11547 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11552 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11553 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11555 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11556 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11557 SetRect(&dst_rect, 0, 0, 480, 360);
11558 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11559 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11560 SetRect(&dst_rect, 0, 0, 320, 240);
11561 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11562 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11564 /* Partial blit. */
11565 SetRect(&src_rect, 0, 0, 320, 240);
11566 SetRect(&dst_rect, 0, 0, 320, 240);
11567 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11568 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11569 /* Flipped. */
11570 SetRect(&src_rect, 0, 0, 640, 480);
11571 SetRect(&dst_rect, 0, 480, 640, 0);
11572 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11573 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11574 /* Full, explicit. */
11575 SetRect(&src_rect, 0, 0, 640, 480);
11576 SetRect(&dst_rect, 0, 0, 640, 480);
11577 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11578 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11579 /* Filtered blit. */
11580 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11581 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11582 /* Depth -> color blit.*/
11583 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11584 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11585 IDirect3DSurface9_Release(backbuffer);
11586 /* Full surface, different sizes */
11587 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11588 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11589 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11590 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11592 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11593 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11594 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11595 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11596 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11597 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11598 IDirect3DSurface9_Release(ds3);
11599 IDirect3DSurface9_Release(ds2);
11600 IDirect3DSurface9_Release(ds1);
11602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11603 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11604 hr = IDirect3DDevice9_BeginScene(device);
11605 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11609 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11610 hr = IDirect3DDevice9_EndScene(device);
11611 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11613 for (i = 0; i < 4; ++i)
11615 for (j = 0; j < 4; ++j)
11617 unsigned int x = 80 * ((2 * j) + 1);
11618 unsigned int y = 60 * ((2 * i) + 1);
11619 color = getPixelColor(device, x, y);
11620 ok(color_match(color, expected_colors[i][j], 0),
11621 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11626 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11629 static void intz_test(IDirect3DDevice9 *device)
11631 static const DWORD ps_code[] =
11633 0xffff0200, /* ps_2_0 */
11634 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11635 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11636 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11637 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11638 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11639 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11640 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11641 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11642 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11643 0x0000ffff, /* end */
11645 struct
11647 float x, y, z;
11648 float s, t, p, q;
11650 quad[] =
11652 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11653 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11654 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11655 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11657 half_quad_1[] =
11659 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11660 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11661 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11662 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11664 half_quad_2[] =
11666 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11667 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11668 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11669 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11671 struct
11673 UINT x, y;
11674 D3DCOLOR color;
11676 expected_colors[] =
11678 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11679 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11680 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11681 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11682 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11683 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11684 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11685 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11688 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11689 IDirect3DTexture9 *texture;
11690 IDirect3DPixelShader9 *ps;
11691 IDirect3DSurface9 *ds;
11692 IDirect3D9 *d3d9;
11693 D3DCAPS9 caps;
11694 HRESULT hr;
11695 UINT i;
11697 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11698 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11699 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11701 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11702 return;
11704 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11706 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11707 return;
11710 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11711 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11713 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11714 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11715 if (FAILED(hr))
11717 skip("No INTZ support, skipping INTZ test.\n");
11718 return;
11721 IDirect3D9_Release(d3d9);
11723 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11724 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11725 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11726 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11728 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11729 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11730 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11731 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11732 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11733 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11734 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11735 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11738 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11740 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11742 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11744 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11746 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11748 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11749 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11750 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11751 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11752 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11753 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11754 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11755 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11757 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11759 /* Render offscreen, using the INTZ texture as depth buffer */
11760 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11761 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11762 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11763 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11764 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11765 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11766 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11767 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11769 /* Setup the depth/stencil surface. */
11770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11771 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11773 hr = IDirect3DDevice9_BeginScene(device);
11774 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11776 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11777 hr = IDirect3DDevice9_EndScene(device);
11778 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11780 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11781 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11782 IDirect3DSurface9_Release(ds);
11783 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11784 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11785 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11786 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11787 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11788 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11790 /* Read the depth values back. */
11791 hr = IDirect3DDevice9_BeginScene(device);
11792 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11794 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11795 hr = IDirect3DDevice9_EndScene(device);
11796 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11798 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11800 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11801 ok(color_match(color, expected_colors[i].color, 1),
11802 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11803 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11806 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11807 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11809 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11810 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11811 IDirect3DTexture9_Release(texture);
11813 /* Render onscreen while using the INTZ texture as depth buffer */
11814 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11815 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11816 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11817 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11818 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11819 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11820 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11821 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11823 /* Setup the depth/stencil surface. */
11824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11825 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11827 hr = IDirect3DDevice9_BeginScene(device);
11828 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11831 hr = IDirect3DDevice9_EndScene(device);
11832 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11834 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11835 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11836 IDirect3DSurface9_Release(ds);
11837 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11838 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11839 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11840 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11842 /* Read the depth values back. */
11843 hr = IDirect3DDevice9_BeginScene(device);
11844 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11846 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11847 hr = IDirect3DDevice9_EndScene(device);
11848 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11850 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11852 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11853 ok(color_match(color, expected_colors[i].color, 1),
11854 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11855 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11858 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11859 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11861 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11862 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11863 IDirect3DTexture9_Release(texture);
11865 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11866 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11867 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11868 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11869 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11871 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11872 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11873 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11874 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11875 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11876 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11878 /* Setup the depth/stencil surface. */
11879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11880 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11882 hr = IDirect3DDevice9_BeginScene(device);
11883 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11885 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11886 hr = IDirect3DDevice9_EndScene(device);
11887 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11889 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11890 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11892 hr = IDirect3DDevice9_BeginScene(device);
11893 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11895 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11896 hr = IDirect3DDevice9_EndScene(device);
11897 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11899 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11900 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11901 IDirect3DSurface9_Release(ds);
11902 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11903 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11904 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11905 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11907 /* Read the depth values back. */
11908 hr = IDirect3DDevice9_BeginScene(device);
11909 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11911 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11912 hr = IDirect3DDevice9_EndScene(device);
11913 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11915 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11917 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11918 ok(color_match(color, expected_colors[i].color, 1),
11919 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11920 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11923 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11924 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11926 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11927 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11928 IDirect3DSurface9_Release(original_ds);
11929 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11930 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11931 IDirect3DTexture9_Release(texture);
11932 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11933 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11934 IDirect3DPixelShader9_Release(ps);
11936 IDirect3DSurface9_Release(original_rt);
11937 IDirect3DSurface9_Release(rt);
11940 static void shadow_test(IDirect3DDevice9 *device)
11942 static const DWORD ps_code[] =
11944 0xffff0200, /* ps_2_0 */
11945 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11946 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11947 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11948 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11949 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11950 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11951 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11952 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11953 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11954 0x0000ffff, /* end */
11956 struct
11958 D3DFORMAT format;
11959 const char *name;
11961 formats[] =
11963 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11964 {D3DFMT_D32, "D3DFMT_D32"},
11965 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11966 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11967 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11968 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11969 {D3DFMT_D16, "D3DFMT_D16"},
11970 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11971 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11973 struct
11975 float x, y, z;
11976 float s, t, p, q;
11978 quad[] =
11980 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11981 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11982 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11983 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11985 struct
11987 UINT x, y;
11988 D3DCOLOR color;
11990 expected_colors[] =
11992 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11993 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11994 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11995 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11996 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11997 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11998 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11999 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12002 IDirect3DSurface9 *original_ds, *original_rt, *rt;
12003 IDirect3DPixelShader9 *ps;
12004 IDirect3D9 *d3d9;
12005 D3DCAPS9 caps;
12006 HRESULT hr;
12007 UINT i;
12009 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12010 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12011 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12013 skip("No pixel shader 2.0 support, skipping shadow test.\n");
12014 return;
12017 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12018 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12019 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12020 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12021 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12022 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12024 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12025 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12026 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12027 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12028 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12030 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12031 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12032 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12033 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12034 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12035 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12036 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12037 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12039 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12041 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12042 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12043 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12044 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12045 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12046 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12047 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12048 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12049 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12050 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12052 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12054 D3DFORMAT format = formats[i].format;
12055 IDirect3DTexture9 *texture;
12056 IDirect3DSurface9 *ds;
12057 unsigned int j;
12059 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12060 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12061 if (FAILED(hr)) continue;
12063 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12064 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12065 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12067 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12068 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12070 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12071 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12073 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12074 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12076 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12077 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12079 /* Setup the depth/stencil surface. */
12080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12081 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12083 hr = IDirect3DDevice9_BeginScene(device);
12084 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12086 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 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12091 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12092 IDirect3DSurface9_Release(ds);
12094 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12095 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12097 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12098 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12100 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12101 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12103 /* Do the actual shadow mapping. */
12104 hr = IDirect3DDevice9_BeginScene(device);
12105 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12107 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12108 hr = IDirect3DDevice9_EndScene(device);
12109 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12111 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12112 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12113 IDirect3DTexture9_Release(texture);
12115 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12117 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12118 ok(color_match(color, expected_colors[j].color, 0),
12119 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12120 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12121 formats[i].name, color);
12124 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12125 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12128 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12129 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12130 IDirect3DPixelShader9_Release(ps);
12132 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12133 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12134 IDirect3DSurface9_Release(original_ds);
12136 IDirect3DSurface9_Release(original_rt);
12137 IDirect3DSurface9_Release(rt);
12139 IDirect3D9_Release(d3d9);
12142 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12144 const struct vertex quad1[] =
12146 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12147 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12148 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
12149 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
12151 const struct vertex quad2[] =
12153 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12154 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12155 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
12156 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
12158 D3DCOLOR color;
12159 HRESULT hr;
12161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12162 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12164 hr = IDirect3DDevice9_BeginScene(device);
12165 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12167 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12168 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12171 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12172 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12173 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12176 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12177 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12178 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12180 hr = IDirect3DDevice9_EndScene(device);
12181 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12183 color = getPixelColor(device, 1, 240);
12184 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12185 color = getPixelColor(device, 638, 240);
12186 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12188 color = getPixelColor(device, 1, 241);
12189 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12190 color = getPixelColor(device, 638, 241);
12191 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12194 static void clip_planes_test(IDirect3DDevice9 *device)
12196 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12198 const DWORD shader_code[] = {
12199 0xfffe0200, /* vs_2_0 */
12200 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12201 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12202 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12203 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12204 0x0000ffff /* end */
12206 IDirect3DVertexShader9 *shader;
12208 IDirect3DTexture9 *offscreen = NULL;
12209 IDirect3DSurface9 *offscreen_surface, *original_rt;
12210 HRESULT hr;
12212 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12213 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12216 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12218 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12220 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12222 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12224 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12225 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12226 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12227 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12229 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12231 clip_planes(device, "Onscreen FFP");
12233 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12234 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12235 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12236 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12237 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12238 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12240 clip_planes(device, "Offscreen FFP");
12242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12243 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12245 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12246 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12247 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12248 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12250 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12251 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12253 clip_planes(device, "Onscreen vertex shader");
12255 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12258 clip_planes(device, "Offscreen vertex shader");
12260 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12261 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12263 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12264 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12265 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12266 IDirect3DVertexShader9_Release(shader);
12267 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12268 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12269 IDirect3DSurface9_Release(original_rt);
12270 IDirect3DSurface9_Release(offscreen_surface);
12271 IDirect3DTexture9_Release(offscreen);
12274 static void fp_special_test(IDirect3DDevice9 *device)
12276 static const DWORD vs_header[] =
12278 0xfffe0200, /* vs_2_0 */
12279 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12280 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12281 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
12284 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
12285 static const DWORD vs_pow[] =
12286 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
12287 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
12288 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
12289 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
12290 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
12291 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
12292 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
12293 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
12295 static const DWORD vs_footer[] =
12297 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
12298 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
12299 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
12300 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
12301 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12302 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
12303 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
12304 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
12305 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12306 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
12307 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
12308 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
12309 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
12310 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
12311 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12312 0x0000ffff, /* end */
12315 static const struct
12317 const char *name;
12318 const DWORD *ops;
12319 DWORD size;
12320 D3DCOLOR r600;
12321 D3DCOLOR nv40;
12322 D3DCOLOR nv50;
12324 vs_body[] =
12326 /* The basic ideas here are:
12327 * 2.0 * +/-INF == +/-INF
12328 * NAN != NAN
12330 * The vertex shader value is written to the red component, with 0.0
12331 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12332 * result in 0x00. The pixel shader value is written to the green
12333 * component, but here 0.0 also results in 0x00. The actual value is
12334 * written to the blue component.
12336 * There are considerable differences between graphics cards in how
12337 * these are handled, but pow and nrm never generate INF or NAN. */
12338 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
12339 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
12340 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
12341 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12342 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
12343 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12344 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12345 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000},
12348 static const DWORD ps_code[] =
12350 0xffff0200, /* ps_2_0 */
12351 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12352 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
12353 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
12354 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
12355 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
12356 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
12357 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
12358 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
12359 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
12360 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
12361 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
12362 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
12363 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
12364 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
12365 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
12366 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
12367 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
12368 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
12369 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
12370 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
12371 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
12372 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12373 0x0000ffff, /* end */
12376 struct
12378 float x, y, z;
12379 float s;
12381 quad[] =
12383 { -1.0f, 1.0f, 0.0f, 0.0f},
12384 { 1.0f, 1.0f, 1.0f, 0.0f},
12385 { -1.0f, -1.0f, 0.0f, 0.0f},
12386 { 1.0f, -1.0f, 1.0f, 0.0f},
12389 IDirect3DPixelShader9 *ps;
12390 UINT body_size = 0;
12391 DWORD *vs_code;
12392 D3DCAPS9 caps;
12393 HRESULT hr;
12394 UINT i;
12396 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12397 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12398 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12400 skip("No shader model 2.0 support, skipping floating point specials test.\n");
12401 return;
12404 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12405 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12407 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12408 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12409 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12410 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12413 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12416 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12418 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12420 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12423 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12424 memcpy(vs_code, vs_header, sizeof(vs_header));
12426 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12428 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12429 IDirect3DVertexShader9 *vs;
12430 D3DCOLOR color;
12432 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12433 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12434 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12436 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12437 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12438 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12439 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12441 hr = IDirect3DDevice9_BeginScene(device);
12442 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12444 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12445 hr = IDirect3DDevice9_EndScene(device);
12446 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12448 color = getPixelColor(device, 320, 240);
12449 ok(color_match(color, vs_body[i].r600, 1)
12450 || color_match(color, vs_body[i].nv40, 1)
12451 || color_match(color, vs_body[i].nv50, 1),
12452 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12453 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12455 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12456 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12458 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12459 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12460 IDirect3DVertexShader9_Release(vs);
12463 HeapFree(GetProcessHeap(), 0, vs_code);
12465 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12466 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12467 IDirect3DPixelShader9_Release(ps);
12470 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12472 IDirect3D9 *d3d;
12473 IDirect3DSurface9 *rt, *backbuffer;
12474 IDirect3DTexture9 *texture;
12475 HRESULT hr;
12476 int i;
12477 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12478 static const struct
12480 D3DFORMAT fmt;
12481 const char *name;
12483 formats[] =
12485 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12486 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12487 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12488 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12489 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12491 static const struct
12493 float x, y, z;
12494 float u, v;
12496 quad[] =
12498 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12499 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12500 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12501 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12504 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12505 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12506 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12507 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12508 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12509 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12510 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12511 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12513 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12515 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12517 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12518 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12520 skip("Format %s not supported as render target, skipping test.\n",
12521 formats[i].name);
12522 continue;
12525 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12526 D3DPOOL_DEFAULT, &texture, NULL);
12527 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12528 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12529 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12531 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12532 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12533 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12534 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12536 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12538 hr = IDirect3DDevice9_BeginScene(device);
12539 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12540 if(SUCCEEDED(hr))
12542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12543 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12544 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12545 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12546 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12547 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12550 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12551 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12552 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12553 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12554 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12555 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12556 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12558 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12559 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12560 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12562 hr = IDirect3DDevice9_EndScene(device);
12563 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12566 IDirect3DSurface9_Release(rt);
12567 IDirect3DTexture9_Release(texture);
12569 color = getPixelColor(device, 360, 240);
12570 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12571 D3DUSAGE_QUERY_SRGBWRITE,
12572 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12574 /* Big slop for R5G6B5 */
12575 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12576 formats[i].name, color_srgb, color);
12578 else
12580 /* Big slop for R5G6B5 */
12581 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12582 formats[i].name, color_rgb, color);
12585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12586 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12589 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12590 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12592 IDirect3D9_Release(d3d);
12593 IDirect3DSurface9_Release(backbuffer);
12596 static void ds_size_test(IDirect3DDevice9 *device)
12598 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12599 HRESULT hr;
12600 DWORD num_passes;
12601 struct
12603 float x, y, z;
12605 quad[] =
12607 {-1.0, -1.0, 0.0 },
12608 {-1.0, 1.0, 0.0 },
12609 { 1.0, -1.0, 0.0 },
12610 { 1.0, 1.0, 0.0 }
12613 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12614 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12615 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12616 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12617 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12618 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12621 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12622 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12623 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12625 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12626 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12627 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12628 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12629 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12630 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12631 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12632 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12633 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12634 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12635 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12636 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12637 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12639 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12640 * but does not change the surface's contents. */
12641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12642 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12644 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12646 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12648 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12650 /* Turning on any depth-related state results in a ValidateDevice failure */
12651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12652 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12653 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12654 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12655 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12657 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12659 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12660 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12661 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12662 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12664 /* Try to draw with the device in an invalid state */
12665 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12666 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12667 hr = IDirect3DDevice9_BeginScene(device);
12668 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12669 if(SUCCEEDED(hr))
12671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12672 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12673 hr = IDirect3DDevice9_EndScene(device);
12674 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12676 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12677 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12678 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12681 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12682 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12683 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12684 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12685 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12686 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12688 IDirect3DSurface9_Release(readback);
12689 IDirect3DSurface9_Release(ds);
12690 IDirect3DSurface9_Release(rt);
12691 IDirect3DSurface9_Release(old_rt);
12692 IDirect3DSurface9_Release(old_ds);
12695 static void unbound_sampler_test(IDirect3DDevice9 *device)
12697 HRESULT hr;
12698 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12699 IDirect3DSurface9 *rt, *old_rt;
12700 DWORD color;
12702 static const DWORD ps_code[] =
12704 0xffff0200, /* ps_2_0 */
12705 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12706 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12707 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12708 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12709 0x0000ffff, /* end */
12711 static const DWORD ps_code_cube[] =
12713 0xffff0200, /* ps_2_0 */
12714 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
12715 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12716 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12717 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12718 0x0000ffff, /* end */
12720 static const DWORD ps_code_volume[] =
12722 0xffff0200, /* ps_2_0 */
12723 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
12724 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12725 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12726 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12727 0x0000ffff, /* end */
12730 static const struct
12732 float x, y, z;
12733 float u, v;
12735 quad[] =
12737 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12738 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12739 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12740 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12743 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12744 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12746 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12747 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12748 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12749 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12750 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12751 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12753 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12754 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12756 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12757 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12759 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12760 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12762 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12763 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12766 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12768 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12769 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12771 hr = IDirect3DDevice9_BeginScene(device);
12772 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12773 if(SUCCEEDED(hr))
12775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12776 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12778 hr = IDirect3DDevice9_EndScene(device);
12779 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12782 color = getPixelColorFromSurface(rt, 32, 32);
12783 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12785 /* Now try with a cube texture */
12786 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12787 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12789 hr = IDirect3DDevice9_BeginScene(device);
12790 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12791 if (SUCCEEDED(hr))
12793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12794 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12796 hr = IDirect3DDevice9_EndScene(device);
12797 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12800 color = getPixelColorFromSurface(rt, 32, 32);
12801 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12803 /* And then with a volume texture */
12804 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12805 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12807 hr = IDirect3DDevice9_BeginScene(device);
12808 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12809 if (SUCCEEDED(hr))
12811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12812 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12814 hr = IDirect3DDevice9_EndScene(device);
12815 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12818 color = getPixelColorFromSurface(rt, 32, 32);
12819 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12821 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12822 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12824 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12825 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12827 IDirect3DSurface9_Release(rt);
12828 IDirect3DSurface9_Release(old_rt);
12829 IDirect3DPixelShader9_Release(ps);
12830 IDirect3DPixelShader9_Release(ps_cube);
12831 IDirect3DPixelShader9_Release(ps_volume);
12834 static void update_surface_test(IDirect3DDevice9 *device)
12836 static const BYTE blocks[][8] =
12838 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12839 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12840 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12841 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12842 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12843 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12844 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12846 static const struct
12848 UINT x, y;
12849 D3DCOLOR color;
12851 expected_colors[] =
12853 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12854 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12855 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12856 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12857 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12858 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12859 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12861 static const struct
12863 float x, y, z, w;
12864 float u, v;
12866 tri[] =
12868 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12869 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12870 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12872 static const RECT rect_2x2 = {0, 0, 2, 2};
12873 static const struct
12875 UINT src_level;
12876 UINT dst_level;
12877 const RECT *r;
12878 HRESULT hr;
12880 block_size_tests[] =
12882 {1, 0, NULL, D3D_OK},
12883 {0, 1, NULL, D3DERR_INVALIDCALL},
12884 {5, 4, NULL, D3DERR_INVALIDCALL},
12885 {4, 5, NULL, D3DERR_INVALIDCALL},
12886 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12887 {5, 5, &rect_2x2, D3D_OK},
12890 IDirect3DSurface9 *src_surface, *dst_surface;
12891 IDirect3DTexture9 *src_tex, *dst_tex;
12892 IDirect3D9 *d3d;
12893 UINT count, i;
12894 HRESULT hr;
12896 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12897 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12899 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12900 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12901 IDirect3D9_Release(d3d);
12902 if (FAILED(hr))
12904 skip("DXT1 not supported, skipping test.\n");
12905 return;
12908 IDirect3D9_Release(d3d);
12910 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12911 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12912 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12913 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12915 count = IDirect3DTexture9_GetLevelCount(src_tex);
12916 ok(count == 7, "Got level count %u, expected 7.\n", count);
12918 for (i = 0; i < count; ++i)
12920 UINT row_count, block_count, x, y;
12921 D3DSURFACE_DESC desc;
12922 BYTE *row, *block;
12923 D3DLOCKED_RECT r;
12925 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12926 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12928 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12929 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12931 row_count = ((desc.Height + 3) & ~3) / 4;
12932 block_count = ((desc.Width + 3) & ~3) / 4;
12933 row = r.pBits;
12935 for (y = 0; y < row_count; ++y)
12937 block = row;
12938 for (x = 0; x < block_count; ++x)
12940 memcpy(block, blocks[i], sizeof(blocks[i]));
12941 block += sizeof(blocks[i]);
12943 row += r.Pitch;
12946 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12947 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12950 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12952 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12953 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12954 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12955 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12957 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12958 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12959 hr, i, block_size_tests[i].hr);
12961 IDirect3DSurface9_Release(dst_surface);
12962 IDirect3DSurface9_Release(src_surface);
12965 for (i = 0; i < count; ++i)
12967 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12968 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12969 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12970 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12972 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12973 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12975 IDirect3DSurface9_Release(dst_surface);
12976 IDirect3DSurface9_Release(src_surface);
12979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12980 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12981 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12982 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12983 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12984 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12985 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12986 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12987 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12988 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12989 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12990 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12992 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12993 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12995 hr = IDirect3DDevice9_BeginScene(device);
12996 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12998 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12999 hr = IDirect3DDevice9_EndScene(device);
13000 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13002 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13004 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13005 ok(color_match(color, expected_colors[i].color, 0),
13006 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13007 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13010 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13011 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13013 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13014 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13015 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13016 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13017 IDirect3DTexture9_Release(dst_tex);
13018 IDirect3DTexture9_Release(src_tex);
13021 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13023 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13024 IDirect3D9 *d3d9;
13025 HRESULT hr;
13027 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13028 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13029 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13030 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13031 IDirect3D9_Release(d3d9);
13032 if (FAILED(hr))
13034 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13035 return;
13038 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13039 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13040 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13041 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13042 D3DPOOL_SYSTEMMEM, &readback, NULL);
13043 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13045 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13046 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13047 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13048 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13050 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13051 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13052 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13053 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13055 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13056 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13057 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13058 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13060 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13061 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13062 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13063 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13065 IDirect3DSurface9_Release(original_ds);
13066 IDirect3DSurface9_Release(original_rt);
13067 IDirect3DSurface9_Release(readback);
13068 IDirect3DSurface9_Release(rt);
13071 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13073 IDirect3DDevice9 *device = 0;
13074 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13075 D3DCAPS9 caps;
13076 HRESULT hr;
13077 D3DPRESENT_PARAMETERS present_parameters;
13078 unsigned int i;
13079 static const struct
13081 float x, y, z;
13082 D3DCOLOR color;
13084 quad_1[] =
13086 { -1.0f, 1.0f, 0.0f, 0xffff0000},
13087 { 1.0f, 1.0f, 1.0f, 0xffff0000},
13088 { -1.0f, -1.0f, 0.0f, 0xffff0000},
13089 { 1.0f, -1.0f, 1.0f, 0xffff0000},
13091 quad_2[] =
13093 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
13094 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
13095 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13096 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
13098 static const struct
13100 UINT x, y;
13101 D3DCOLOR color;
13103 expected_colors[] =
13105 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13106 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13107 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13108 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13109 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13110 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13111 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13112 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13115 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13116 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13117 if (FAILED(hr))
13119 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13120 return;
13122 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13123 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13124 if (FAILED(hr))
13126 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13127 return;
13130 ZeroMemory(&present_parameters, sizeof(present_parameters));
13131 present_parameters.Windowed = TRUE;
13132 present_parameters.hDeviceWindow = create_window();
13133 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13134 present_parameters.BackBufferWidth = 640;
13135 present_parameters.BackBufferHeight = 480;
13136 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13137 present_parameters.EnableAutoDepthStencil = TRUE;
13138 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13139 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13141 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13142 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13143 &present_parameters, &device);
13144 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13146 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13147 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13148 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13150 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13151 goto cleanup;
13154 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13155 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13156 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13157 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13158 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13159 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13161 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13162 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13163 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13164 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13167 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13169 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13171 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13173 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13174 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13175 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13178 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13180 /* Render onscreen and then offscreen */
13181 hr = IDirect3DDevice9_BeginScene(device);
13182 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13184 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13185 hr = IDirect3DDevice9_EndScene(device);
13186 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13188 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13189 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13190 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13191 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_BeginScene(device);
13194 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13195 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13196 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13197 hr = IDirect3DDevice9_EndScene(device);
13198 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13200 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13201 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13203 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13205 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13206 ok(color_match(color, expected_colors[i].color, 1),
13207 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13208 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13211 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13212 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13213 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13214 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13216 /* Render offscreen and then onscreen */
13217 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13218 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13219 IDirect3DSurface9_Release(ds);
13220 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13221 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13222 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13223 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
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_SetRenderTarget(device, 0, original_rt);
13238 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13240 hr = IDirect3DDevice9_BeginScene(device);
13241 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13243 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13244 hr = IDirect3DDevice9_EndScene(device);
13245 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13247 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13248 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13250 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13252 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13253 ok(color_match(color, expected_colors[i].color, 1),
13254 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13255 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13258 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13259 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13261 IDirect3DSurface9_Release(ds);
13262 IDirect3DSurface9_Release(readback);
13263 IDirect3DSurface9_Release(rt);
13264 IDirect3DSurface9_Release(original_rt);
13265 cleanup_device(device);
13267 ZeroMemory(&present_parameters, sizeof(present_parameters));
13268 present_parameters.Windowed = TRUE;
13269 present_parameters.hDeviceWindow = create_window();
13270 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13271 present_parameters.BackBufferWidth = 640;
13272 present_parameters.BackBufferHeight = 480;
13273 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13274 present_parameters.EnableAutoDepthStencil = TRUE;
13275 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13276 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13278 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13279 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13280 &present_parameters, &device);
13281 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13283 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13284 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13286 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13287 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13288 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13289 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13290 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13291 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13292 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13293 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13294 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13296 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13297 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13298 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13299 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13300 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13301 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13302 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13303 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13306 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13308 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13310 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13312 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13313 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13314 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13316 /* Render to a multisampled offscreen frame buffer and then blit to
13317 * the onscreen (not multisampled) frame buffer. */
13318 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13319 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13321 hr = IDirect3DDevice9_BeginScene(device);
13322 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13324 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13325 hr = IDirect3DDevice9_EndScene(device);
13326 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13328 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13329 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13330 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13331 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13333 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13334 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13335 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13336 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13338 hr = IDirect3DDevice9_BeginScene(device);
13339 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13341 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13342 hr = IDirect3DDevice9_EndScene(device);
13343 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13345 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13346 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13348 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13350 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13351 if (i % 4 < 2)
13352 todo_wine ok(color_match(color, expected_colors[i].color, 1),
13353 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13354 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13355 else
13356 ok(color_match(color, expected_colors[i].color, 1),
13357 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13358 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13362 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13364 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13365 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13366 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13367 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13369 IDirect3DSurface9_Release(original_ds);
13370 IDirect3DSurface9_Release(original_rt);
13371 IDirect3DSurface9_Release(ds);
13372 IDirect3DSurface9_Release(readback);
13373 IDirect3DSurface9_Release(rt);
13374 cleanup:
13375 cleanup_device(device);
13378 static void resz_test(IDirect3D9 *d3d9)
13380 IDirect3DDevice9 *device = 0;
13381 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13382 D3DCAPS9 caps;
13383 HRESULT hr;
13384 D3DPRESENT_PARAMETERS present_parameters;
13385 unsigned int i;
13386 static const DWORD ps_code[] =
13388 0xffff0200, /* ps_2_0 */
13389 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13390 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13391 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13392 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13393 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13394 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13395 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13396 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13397 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13398 0x0000ffff, /* end */
13400 struct
13402 float x, y, z;
13403 float s, t, p, q;
13405 quad[] =
13407 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13408 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13409 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13410 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13412 struct
13414 UINT x, y;
13415 D3DCOLOR color;
13417 expected_colors[] =
13419 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13420 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13421 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13422 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13423 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13424 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13425 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13426 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13428 IDirect3DTexture9 *texture;
13429 IDirect3DPixelShader9 *ps;
13430 DWORD value;
13432 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13433 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13434 if (FAILED(hr))
13436 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13437 return;
13439 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13440 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13441 if (FAILED(hr))
13443 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13444 return;
13447 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13448 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13449 if (FAILED(hr))
13451 skip("No INTZ support, skipping RESZ test.\n");
13452 return;
13455 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13456 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13457 if (FAILED(hr))
13459 skip("No RESZ support, skipping RESZ test.\n");
13460 return;
13463 ZeroMemory(&present_parameters, sizeof(present_parameters));
13464 present_parameters.Windowed = TRUE;
13465 present_parameters.hDeviceWindow = create_window();
13466 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13467 present_parameters.BackBufferWidth = 640;
13468 present_parameters.BackBufferHeight = 480;
13469 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13470 present_parameters.EnableAutoDepthStencil = FALSE;
13471 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13472 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13474 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13475 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13476 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13478 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13479 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13480 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13482 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13483 cleanup_device(device);
13484 return;
13486 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13488 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13489 cleanup_device(device);
13490 return;
13493 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13494 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13496 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13497 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13498 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13499 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13500 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13501 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13502 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13503 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13505 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13506 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13507 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13508 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13509 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13510 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13511 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13513 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13514 IDirect3DSurface9_Release(intz_ds);
13515 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13516 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13518 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13519 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13521 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13523 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13525 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13527 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13530 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13531 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13532 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13533 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13534 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13535 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13536 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13537 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13538 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13540 /* Render offscreen (multisampled), blit the depth buffer
13541 * into the INTZ texture and then check its contents */
13542 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13543 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13544 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13545 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13546 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13547 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13549 hr = IDirect3DDevice9_BeginScene(device);
13550 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13552 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13554 /* The destination depth texture has to be bound to sampler 0 */
13555 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13556 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13558 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13560 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13562 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13564 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13566 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13568 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13570 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13572 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13574 /* The actual multisampled depth buffer resolve happens here */
13575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13576 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13577 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13578 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13580 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13581 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13582 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13583 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13585 /* Read the depth values back */
13586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13587 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13588 hr = IDirect3DDevice9_EndScene(device);
13589 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13591 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13593 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13594 ok(color_match(color, expected_colors[i].color, 1),
13595 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13596 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13600 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13602 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13603 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13604 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13605 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13606 IDirect3DSurface9_Release(ds);
13607 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13608 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13609 IDirect3DTexture9_Release(texture);
13610 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13611 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13612 IDirect3DPixelShader9_Release(ps);
13613 IDirect3DSurface9_Release(readback);
13614 IDirect3DSurface9_Release(original_rt);
13615 IDirect3DSurface9_Release(rt);
13616 cleanup_device(device);
13619 ZeroMemory(&present_parameters, sizeof(present_parameters));
13620 present_parameters.Windowed = TRUE;
13621 present_parameters.hDeviceWindow = create_window();
13622 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13623 present_parameters.BackBufferWidth = 640;
13624 present_parameters.BackBufferHeight = 480;
13625 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13626 present_parameters.EnableAutoDepthStencil = TRUE;
13627 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13628 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13630 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13631 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13632 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13634 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13635 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13636 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13637 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13638 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13639 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13640 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13641 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13642 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13643 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13644 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13645 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13646 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13647 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13648 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13649 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13651 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13652 IDirect3DSurface9_Release(intz_ds);
13653 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13654 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13656 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13657 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13659 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13661 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13662 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13663 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13664 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13665 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13667 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13668 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13669 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13670 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13671 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13672 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13673 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13674 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13675 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13676 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13678 /* Render onscreen, blit the depth buffer into the INTZ texture
13679 * and then check its contents */
13680 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13681 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13682 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13683 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13685 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13687 hr = IDirect3DDevice9_BeginScene(device);
13688 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13690 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13691 hr = IDirect3DDevice9_EndScene(device);
13692 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13694 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13695 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13698 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13700 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13702 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13704 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13706 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13708 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13710 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13712 /* The actual multisampled depth buffer resolve happens here */
13713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13714 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13715 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13716 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13718 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13719 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13720 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13721 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13723 /* Read the depth values back */
13724 hr = IDirect3DDevice9_BeginScene(device);
13725 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13727 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13728 hr = IDirect3DDevice9_EndScene(device);
13729 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13731 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13733 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13734 ok(color_match(color, expected_colors[i].color, 1),
13735 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13736 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13739 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13740 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13743 /* Test edge cases - try with no texture at all */
13744 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13745 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13746 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13747 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13749 hr = IDirect3DDevice9_BeginScene(device);
13750 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13752 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13753 hr = IDirect3DDevice9_EndScene(device);
13754 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13757 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13759 /* With a non-multisampled depth buffer */
13760 IDirect3DSurface9_Release(ds);
13761 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13762 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13764 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13765 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13766 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13767 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13768 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13769 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13771 hr = IDirect3DDevice9_BeginScene(device);
13772 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13774 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13776 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13777 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13780 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13782 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13784 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13786 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13788 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13790 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13791 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13792 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13793 hr = IDirect3DDevice9_EndScene(device);
13794 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13797 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13799 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13800 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13802 /* Read the depth values back. */
13803 hr = IDirect3DDevice9_BeginScene(device);
13804 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13806 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13807 hr = IDirect3DDevice9_EndScene(device);
13808 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13810 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13812 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13813 ok(color_match(color, expected_colors[i].color, 1),
13814 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13815 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13819 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13821 /* Without a current depth-stencil buffer set */
13822 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13823 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13824 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13825 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13827 hr = IDirect3DDevice9_BeginScene(device);
13828 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13831 hr = IDirect3DDevice9_EndScene(device);
13832 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13835 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13837 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13838 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13839 IDirect3DSurface9_Release(ds);
13840 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13841 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13842 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13843 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13844 IDirect3DTexture9_Release(texture);
13845 IDirect3DPixelShader9_Release(ps);
13846 IDirect3DSurface9_Release(readback);
13847 IDirect3DSurface9_Release(original_rt);
13848 cleanup_device(device);
13851 static void zenable_test(IDirect3DDevice9 *device)
13853 static const struct
13855 struct vec4 position;
13856 D3DCOLOR diffuse;
13858 tquad[] =
13860 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13861 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
13862 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
13863 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
13865 D3DCOLOR color;
13866 D3DCAPS9 caps;
13867 HRESULT hr;
13868 UINT x, y;
13869 UINT i, j;
13871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13872 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13874 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13877 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13878 hr = IDirect3DDevice9_BeginScene(device);
13879 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13881 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13882 hr = IDirect3DDevice9_EndScene(device);
13883 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13885 for (i = 0; i < 4; ++i)
13887 for (j = 0; j < 4; ++j)
13889 x = 80 * ((2 * j) + 1);
13890 y = 60 * ((2 * i) + 1);
13891 color = getPixelColor(device, x, y);
13892 ok(color_match(color, 0x0000ff00, 1),
13893 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13897 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13898 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13900 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13901 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13903 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13904 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13906 static const DWORD vs_code[] =
13908 0xfffe0101, /* vs_1_1 */
13909 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13910 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13911 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
13912 0x0000ffff
13914 static const DWORD ps_code[] =
13916 0xffff0101, /* ps_1_1 */
13917 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
13918 0x0000ffff /* end */
13920 static const struct vec3 quad[] =
13922 {-1.0f, -1.0f, -0.5f},
13923 {-1.0f, 1.0f, -0.5f},
13924 { 1.0f, -1.0f, 1.5f},
13925 { 1.0f, 1.0f, 1.5f},
13927 static const D3DCOLOR expected[] =
13929 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13930 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13931 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13932 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13935 IDirect3DVertexShader9 *vs;
13936 IDirect3DPixelShader9 *ps;
13938 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13939 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13940 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13941 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13942 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13943 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13944 hr = IDirect3DDevice9_SetVertexShader(device, vs);
13945 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13946 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13947 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13949 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13950 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13951 hr = IDirect3DDevice9_BeginScene(device);
13952 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13954 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13955 hr = IDirect3DDevice9_EndScene(device);
13956 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13958 for (i = 0; i < 4; ++i)
13960 for (j = 0; j < 4; ++j)
13962 x = 80 * ((2 * j) + 1);
13963 y = 60 * ((2 * i) + 1);
13964 color = getPixelColor(device, x, y);
13965 ok(color_match(color, expected[i * 4 + j], 1),
13966 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13970 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13971 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13973 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13974 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13975 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13976 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13977 IDirect3DPixelShader9_Release(ps);
13978 IDirect3DVertexShader9_Release(vs);
13982 START_TEST(visual)
13984 IDirect3D9 *d3d9;
13985 IDirect3DDevice9 *device_ptr;
13986 D3DCAPS9 caps;
13987 HRESULT hr;
13988 DWORD color;
13990 d3d9_handle = LoadLibraryA("d3d9.dll");
13991 if (!d3d9_handle)
13993 skip("Could not load d3d9.dll\n");
13994 return;
13997 device_ptr = init_d3d9();
13998 if (!device_ptr)
14000 skip("Creating the device failed\n");
14001 return;
14004 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14006 /* Check for the reliability of the returned data */
14007 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14008 if(FAILED(hr))
14010 skip("Clear failed, can't assure correctness of the test results, skipping\n");
14011 goto cleanup;
14014 color = getPixelColor(device_ptr, 1, 1);
14015 if(color !=0x00ff0000)
14017 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14018 goto cleanup;
14020 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14022 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14023 if(FAILED(hr))
14025 skip("Clear failed, can't assure correctness of the test results, skipping\n");
14026 goto cleanup;
14029 color = getPixelColor(device_ptr, 639, 479);
14030 if(color != 0x0000ddee)
14032 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14033 goto cleanup;
14035 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14037 /* Now execute the real tests */
14038 depth_clamp_test(device_ptr);
14039 stretchrect_test(device_ptr);
14040 lighting_test(device_ptr);
14041 clear_test(device_ptr);
14042 color_fill_test(device_ptr);
14043 fog_test(device_ptr);
14044 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14046 test_cube_wrap(device_ptr);
14047 } else {
14048 skip("No cube texture support\n");
14050 z_range_test(device_ptr);
14051 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14053 maxmip_test(device_ptr);
14055 else
14057 skip("No mipmap support\n");
14059 offscreen_test(device_ptr);
14060 ds_size_test(device_ptr);
14061 alpha_test(device_ptr);
14062 shademode_test(device_ptr);
14063 srgbtexture_test(device_ptr);
14064 release_buffer_test(device_ptr);
14065 float_texture_test(device_ptr);
14066 g16r16_texture_test(device_ptr);
14067 pixelshader_blending_test(device_ptr);
14068 texture_transform_flags_test(device_ptr);
14069 autogen_mipmap_test(device_ptr);
14070 fixed_function_decl_test(device_ptr);
14071 conditional_np2_repeat_test(device_ptr);
14072 fixed_function_bumpmap_test(device_ptr);
14073 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14074 stencil_cull_test(device_ptr);
14075 } else {
14076 skip("No two sided stencil support\n");
14078 pointsize_test(device_ptr);
14079 tssargtemp_test(device_ptr);
14080 np2_stretch_rect_test(device_ptr);
14081 yuv_color_test(device_ptr);
14082 zwriteenable_test(device_ptr);
14083 alphatest_test(device_ptr);
14084 viewport_test(device_ptr);
14086 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14088 test_constant_clamp_vs(device_ptr);
14089 test_compare_instructions(device_ptr);
14091 else skip("No vs_1_1 support\n");
14093 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14095 test_mova(device_ptr);
14096 loop_index_test(device_ptr);
14097 sincos_test(device_ptr);
14098 sgn_test(device_ptr);
14099 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14100 test_vshader_input(device_ptr);
14101 test_vshader_float16(device_ptr);
14102 stream_test(device_ptr);
14103 } else {
14104 skip("No vs_3_0 support\n");
14107 else skip("No vs_2_0 support\n");
14109 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14111 fog_with_shader_test(device_ptr);
14113 else skip("No vs_2_0 and ps_2_0 support\n");
14115 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14117 texbem_test(device_ptr);
14118 texdepth_test(device_ptr);
14119 texkill_test(device_ptr);
14120 x8l8v8u8_test(device_ptr);
14121 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14122 constant_clamp_ps_test(device_ptr);
14123 cnd_test(device_ptr);
14124 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14125 dp2add_ps_test(device_ptr);
14126 unbound_sampler_test(device_ptr);
14127 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14128 nested_loop_test(device_ptr);
14129 pretransformed_varying_test(device_ptr);
14130 vFace_register_test(device_ptr);
14131 vpos_register_test(device_ptr);
14132 multiple_rendertargets_test(device_ptr);
14133 } else {
14134 skip("No ps_3_0 or vs_3_0 support\n");
14136 } else {
14137 skip("No ps_2_0 support\n");
14141 else skip("No ps_1_1 support\n");
14143 texop_test(device_ptr);
14144 texop_range_test(device_ptr);
14145 alphareplicate_test(device_ptr);
14146 dp3_alpha_test(device_ptr);
14147 depth_buffer_test(device_ptr);
14148 depth_buffer2_test(device_ptr);
14149 depth_blit_test(device_ptr);
14150 intz_test(device_ptr);
14151 shadow_test(device_ptr);
14152 fp_special_test(device_ptr);
14153 depth_bounds_test(device_ptr);
14154 srgbwrite_format_test(device_ptr);
14155 clip_planes_test(device_ptr);
14156 update_surface_test(device_ptr);
14157 multisample_get_rtdata_test(device_ptr);
14158 zenable_test(device_ptr);
14160 hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14161 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14162 cleanup_device(device_ptr);
14163 device_ptr = NULL;
14165 multisampled_depth_buffer_test(d3d9);
14166 resz_test(d3d9);
14168 IDirect3D9_Release(d3d9);
14170 cleanup:
14171 cleanup_device(device_ptr);