Add AppDefaults app selection to control panel
[wine/gsoc-2012-control.git] / dlls / d3d9 / tests / visual.c
bloba67ce52c1b886dedf1bebee468cb6c78100894ac
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);
11366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11369 hr = IDirect3DDevice9_BeginScene(device);
11370 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11372 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11374 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11375 hr = IDirect3DDevice9_EndScene(device);
11376 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11378 for (i = 0; i < 4; ++i)
11380 for (j = 0; j < 4; ++j)
11382 unsigned int x = 80 * ((2 * j) + 1);
11383 unsigned int y = 60 * ((2 * i) + 1);
11384 color = getPixelColor(device, x, y);
11385 ok(color_match(color, expected_colors[i][j], 0),
11386 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11390 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11391 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11393 IDirect3DSurface9_Release(backbuffer);
11394 IDirect3DSurface9_Release(rt3);
11395 IDirect3DSurface9_Release(rt2);
11396 IDirect3DSurface9_Release(rt1);
11399 /* Test that partial depth copies work the way they're supposed to. The clear
11400 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11401 * the following draw should only copy back the part that was modified. */
11402 static void depth_buffer2_test(IDirect3DDevice9 *device)
11404 static const struct vertex quad[] =
11406 { -1.0, 1.0, 0.66f, 0xffff0000},
11407 { 1.0, 1.0, 0.66f, 0xffff0000},
11408 { -1.0, -1.0, 0.66f, 0xffff0000},
11409 { 1.0, -1.0, 0.66f, 0xffff0000},
11412 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11413 unsigned int i, j;
11414 D3DVIEWPORT9 vp;
11415 D3DCOLOR color;
11416 HRESULT hr;
11418 vp.X = 0;
11419 vp.Y = 0;
11420 vp.Width = 640;
11421 vp.Height = 480;
11422 vp.MinZ = 0.0;
11423 vp.MaxZ = 1.0;
11425 hr = IDirect3DDevice9_SetViewport(device, &vp);
11426 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11428 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11429 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11431 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11433 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11435 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11436 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11437 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11439 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11440 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11441 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11442 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11443 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11444 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11445 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11446 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11448 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11449 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11450 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11451 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11453 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11454 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11455 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11456 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11458 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11459 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11461 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11463 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11464 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11467 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11469 hr = IDirect3DDevice9_BeginScene(device);
11470 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11472 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11473 hr = IDirect3DDevice9_EndScene(device);
11474 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11476 for (i = 0; i < 4; ++i)
11478 for (j = 0; j < 4; ++j)
11480 unsigned int x = 80 * ((2 * j) + 1);
11481 unsigned int y = 60 * ((2 * i) + 1);
11482 color = getPixelColor(device, x, y);
11483 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11484 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11488 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11489 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11491 IDirect3DSurface9_Release(backbuffer);
11492 IDirect3DSurface9_Release(rt2);
11493 IDirect3DSurface9_Release(rt1);
11496 static void depth_blit_test(IDirect3DDevice9 *device)
11498 static const struct vertex quad1[] =
11500 { -1.0, 1.0, 0.50f, 0xff00ff00},
11501 { 1.0, 1.0, 0.50f, 0xff00ff00},
11502 { -1.0, -1.0, 0.50f, 0xff00ff00},
11503 { 1.0, -1.0, 0.50f, 0xff00ff00},
11505 static const struct vertex quad2[] =
11507 { -1.0, 1.0, 0.66f, 0xff0000ff},
11508 { 1.0, 1.0, 0.66f, 0xff0000ff},
11509 { -1.0, -1.0, 0.66f, 0xff0000ff},
11510 { 1.0, -1.0, 0.66f, 0xff0000ff},
11512 static const DWORD expected_colors[4][4] =
11514 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11515 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11516 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11517 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11520 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11521 RECT src_rect, dst_rect;
11522 unsigned int i, j;
11523 D3DVIEWPORT9 vp;
11524 D3DCOLOR color;
11525 HRESULT hr;
11527 vp.X = 0;
11528 vp.Y = 0;
11529 vp.Width = 640;
11530 vp.Height = 480;
11531 vp.MinZ = 0.0;
11532 vp.MaxZ = 1.0;
11534 hr = IDirect3DDevice9_SetViewport(device, &vp);
11535 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11537 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11538 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11539 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11540 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11541 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11542 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11543 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11544 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11545 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11546 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11553 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11554 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11555 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11557 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11558 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11559 SetRect(&dst_rect, 0, 0, 480, 360);
11560 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11561 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11562 SetRect(&dst_rect, 0, 0, 320, 240);
11563 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11564 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11566 /* Partial blit. */
11567 SetRect(&src_rect, 0, 0, 320, 240);
11568 SetRect(&dst_rect, 0, 0, 320, 240);
11569 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11570 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11571 /* Flipped. */
11572 SetRect(&src_rect, 0, 0, 640, 480);
11573 SetRect(&dst_rect, 0, 480, 640, 0);
11574 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11575 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11576 /* Full, explicit. */
11577 SetRect(&src_rect, 0, 0, 640, 480);
11578 SetRect(&dst_rect, 0, 0, 640, 480);
11579 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11580 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11581 /* Filtered blit. */
11582 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11583 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11584 /* Depth -> color blit.*/
11585 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11586 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11587 IDirect3DSurface9_Release(backbuffer);
11588 /* Full surface, different sizes */
11589 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11590 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11591 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11592 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11594 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11595 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11596 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11597 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11598 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11599 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11601 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11602 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11603 hr = IDirect3DDevice9_BeginScene(device);
11604 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11605 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11606 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11607 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11608 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11609 hr = IDirect3DDevice9_EndScene(device);
11610 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11612 for (i = 0; i < 4; ++i)
11614 for (j = 0; j < 4; ++j)
11616 unsigned int x = 80 * ((2 * j) + 1);
11617 unsigned int y = 60 * ((2 * i) + 1);
11618 color = getPixelColor(device, x, y);
11619 ok(color_match(color, expected_colors[i][j], 0),
11620 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11624 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11625 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11627 IDirect3DSurface9_Release(ds3);
11628 IDirect3DSurface9_Release(ds2);
11629 IDirect3DSurface9_Release(ds1);
11632 static void intz_test(IDirect3DDevice9 *device)
11634 static const DWORD ps_code[] =
11636 0xffff0200, /* ps_2_0 */
11637 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11638 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11639 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11640 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11641 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11642 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11643 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11644 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11645 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11646 0x0000ffff, /* end */
11648 struct
11650 float x, y, z;
11651 float s, t, p, q;
11653 quad[] =
11655 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11656 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11657 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11658 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11660 half_quad_1[] =
11662 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11663 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11664 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11665 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11667 half_quad_2[] =
11669 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11670 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11671 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11672 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11674 struct
11676 UINT x, y;
11677 D3DCOLOR color;
11679 expected_colors[] =
11681 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11682 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11683 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11684 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11685 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11686 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11687 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11688 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11691 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11692 IDirect3DTexture9 *texture;
11693 IDirect3DPixelShader9 *ps;
11694 IDirect3DSurface9 *ds;
11695 IDirect3D9 *d3d9;
11696 D3DCAPS9 caps;
11697 HRESULT hr;
11698 UINT i;
11700 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11701 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11702 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11704 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11705 return;
11707 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11709 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11710 return;
11713 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11714 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11716 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11717 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11718 if (FAILED(hr))
11720 skip("No INTZ support, skipping INTZ test.\n");
11721 return;
11724 IDirect3D9_Release(d3d9);
11726 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11727 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11728 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11729 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11731 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11732 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11733 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11734 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11735 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11736 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11737 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11738 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11740 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11741 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11743 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11745 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11747 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11749 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11751 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11752 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11753 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11754 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11755 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11756 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11757 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11758 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11759 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11760 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11762 /* Render offscreen, using the INTZ texture as depth buffer */
11763 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11764 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11765 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11766 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11767 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11768 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11769 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11770 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11772 /* Setup the depth/stencil surface. */
11773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11774 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11776 hr = IDirect3DDevice9_BeginScene(device);
11777 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11779 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11780 hr = IDirect3DDevice9_EndScene(device);
11781 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11783 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11784 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11785 IDirect3DSurface9_Release(ds);
11786 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11787 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11788 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11789 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11790 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11791 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11793 /* Read the depth values back. */
11794 hr = IDirect3DDevice9_BeginScene(device);
11795 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11797 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11798 hr = IDirect3DDevice9_EndScene(device);
11799 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11801 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11803 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11804 ok(color_match(color, expected_colors[i].color, 1),
11805 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11806 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11809 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11810 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11812 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11813 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11814 IDirect3DTexture9_Release(texture);
11816 /* Render onscreen while using the INTZ texture as depth buffer */
11817 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11818 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11819 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11820 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11821 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11822 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11823 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11824 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11826 /* Setup the depth/stencil surface. */
11827 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11828 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11830 hr = IDirect3DDevice9_BeginScene(device);
11831 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11833 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11834 hr = IDirect3DDevice9_EndScene(device);
11835 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11837 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11838 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11839 IDirect3DSurface9_Release(ds);
11840 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11841 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11842 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11843 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11845 /* Read the depth values back. */
11846 hr = IDirect3DDevice9_BeginScene(device);
11847 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11849 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11850 hr = IDirect3DDevice9_EndScene(device);
11851 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11853 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11855 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11856 ok(color_match(color, expected_colors[i].color, 1),
11857 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11858 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11861 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11862 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11864 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11865 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11866 IDirect3DTexture9_Release(texture);
11868 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11869 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11870 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11871 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11872 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11874 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11875 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11876 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11877 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11878 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11879 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11881 /* Setup the depth/stencil surface. */
11882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11883 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11885 hr = IDirect3DDevice9_BeginScene(device);
11886 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11887 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11888 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11889 hr = IDirect3DDevice9_EndScene(device);
11890 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11892 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11893 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11895 hr = IDirect3DDevice9_BeginScene(device);
11896 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11898 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11899 hr = IDirect3DDevice9_EndScene(device);
11900 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11902 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11903 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11904 IDirect3DSurface9_Release(ds);
11905 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11906 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11907 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11908 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11910 /* Read the depth values back. */
11911 hr = IDirect3DDevice9_BeginScene(device);
11912 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11913 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11914 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11915 hr = IDirect3DDevice9_EndScene(device);
11916 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11918 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11920 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11921 ok(color_match(color, expected_colors[i].color, 1),
11922 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11923 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11927 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11929 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11930 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11931 IDirect3DSurface9_Release(original_ds);
11932 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11933 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11934 IDirect3DTexture9_Release(texture);
11935 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11936 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11937 IDirect3DPixelShader9_Release(ps);
11939 IDirect3DSurface9_Release(original_rt);
11940 IDirect3DSurface9_Release(rt);
11943 static void shadow_test(IDirect3DDevice9 *device)
11945 static const DWORD ps_code[] =
11947 0xffff0200, /* ps_2_0 */
11948 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11949 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11950 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11951 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11952 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11953 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11954 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11955 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11956 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11957 0x0000ffff, /* end */
11959 struct
11961 D3DFORMAT format;
11962 const char *name;
11964 formats[] =
11966 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11967 {D3DFMT_D32, "D3DFMT_D32"},
11968 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11969 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11970 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11971 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11972 {D3DFMT_D16, "D3DFMT_D16"},
11973 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11974 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11976 struct
11978 float x, y, z;
11979 float s, t, p, q;
11981 quad[] =
11983 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11984 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11985 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11986 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11988 struct
11990 UINT x, y;
11991 D3DCOLOR color;
11993 expected_colors[] =
11995 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11996 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11997 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11998 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11999 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12000 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12001 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12002 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12005 IDirect3DSurface9 *original_ds, *original_rt, *rt;
12006 IDirect3DPixelShader9 *ps;
12007 IDirect3D9 *d3d9;
12008 D3DCAPS9 caps;
12009 HRESULT hr;
12010 UINT i;
12012 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12013 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12014 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12016 skip("No pixel shader 2.0 support, skipping shadow test.\n");
12017 return;
12020 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12021 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12022 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12023 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12024 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12025 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12027 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12028 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12029 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12030 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12031 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12033 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12034 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12036 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12038 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12039 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12040 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12042 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12044 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12045 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12046 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12047 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12048 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12049 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12050 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12051 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12052 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12053 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12055 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12057 D3DFORMAT format = formats[i].format;
12058 IDirect3DTexture9 *texture;
12059 IDirect3DSurface9 *ds;
12060 unsigned int j;
12062 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12063 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12064 if (FAILED(hr)) continue;
12066 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12067 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12068 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12070 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12071 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12073 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12074 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12076 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12077 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12079 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12080 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12082 /* Setup the depth/stencil surface. */
12083 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12084 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12086 hr = IDirect3DDevice9_BeginScene(device);
12087 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12089 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12090 hr = IDirect3DDevice9_EndScene(device);
12091 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12093 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12094 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12095 IDirect3DSurface9_Release(ds);
12097 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12098 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12100 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12101 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12103 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12104 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12106 /* Do the actual shadow mapping. */
12107 hr = IDirect3DDevice9_BeginScene(device);
12108 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12109 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12110 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12111 hr = IDirect3DDevice9_EndScene(device);
12112 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12114 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12115 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12116 IDirect3DTexture9_Release(texture);
12118 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12120 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12121 ok(color_match(color, expected_colors[j].color, 0),
12122 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12123 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12124 formats[i].name, color);
12127 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12128 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12131 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12132 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12133 IDirect3DPixelShader9_Release(ps);
12135 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12136 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12137 IDirect3DSurface9_Release(original_ds);
12139 IDirect3DSurface9_Release(original_rt);
12140 IDirect3DSurface9_Release(rt);
12142 IDirect3D9_Release(d3d9);
12145 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12147 const struct vertex quad1[] =
12149 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12150 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12151 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
12152 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
12154 const struct vertex quad2[] =
12156 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12157 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12158 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
12159 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
12161 D3DCOLOR color;
12162 HRESULT hr;
12164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12165 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12167 hr = IDirect3DDevice9_BeginScene(device);
12168 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12170 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12171 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12174 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12176 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12179 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12180 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12181 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12183 hr = IDirect3DDevice9_EndScene(device);
12184 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12186 color = getPixelColor(device, 1, 240);
12187 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12188 color = getPixelColor(device, 638, 240);
12189 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12191 color = getPixelColor(device, 1, 241);
12192 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12193 color = getPixelColor(device, 638, 241);
12194 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12197 static void clip_planes_test(IDirect3DDevice9 *device)
12199 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12201 const DWORD shader_code[] = {
12202 0xfffe0200, /* vs_2_0 */
12203 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12204 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12205 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12206 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12207 0x0000ffff /* end */
12209 IDirect3DVertexShader9 *shader;
12211 IDirect3DTexture9 *offscreen = NULL;
12212 IDirect3DSurface9 *offscreen_surface, *original_rt;
12213 HRESULT hr;
12215 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12216 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12219 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12221 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12222 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12223 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12224 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12225 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12227 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12228 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12229 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12230 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12232 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12234 clip_planes(device, "Onscreen FFP");
12236 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12237 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12238 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12239 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12240 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12243 clip_planes(device, "Offscreen FFP");
12245 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12246 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12248 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12249 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12250 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12251 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12253 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12256 clip_planes(device, "Onscreen vertex shader");
12258 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12259 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12261 clip_planes(device, "Offscreen vertex shader");
12263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12264 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12266 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12267 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12268 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12269 IDirect3DVertexShader9_Release(shader);
12270 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12272 IDirect3DSurface9_Release(original_rt);
12273 IDirect3DSurface9_Release(offscreen_surface);
12274 IDirect3DTexture9_Release(offscreen);
12277 static void fp_special_test(IDirect3DDevice9 *device)
12279 static const DWORD vs_header[] =
12281 0xfffe0200, /* vs_2_0 */
12282 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12283 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12284 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
12287 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
12288 static const DWORD vs_pow[] =
12289 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
12290 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
12291 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
12292 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
12293 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
12294 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
12295 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
12296 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
12298 static const DWORD vs_footer[] =
12300 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
12301 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
12302 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
12303 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
12304 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12305 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
12306 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
12307 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
12308 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
12309 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
12310 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
12311 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
12312 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
12313 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
12314 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12315 0x0000ffff, /* end */
12318 static const struct
12320 const char *name;
12321 const DWORD *ops;
12322 DWORD size;
12323 D3DCOLOR r600;
12324 D3DCOLOR nv40;
12325 D3DCOLOR nv50;
12327 vs_body[] =
12329 /* The basic ideas here are:
12330 * 2.0 * +/-INF == +/-INF
12331 * NAN != NAN
12333 * The vertex shader value is written to the red component, with 0.0
12334 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12335 * result in 0x00. The pixel shader value is written to the green
12336 * component, but here 0.0 also results in 0x00. The actual value is
12337 * written to the blue component.
12339 * There are considerable differences between graphics cards in how
12340 * these are handled, but pow and nrm never generate INF or NAN. */
12341 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
12342 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
12343 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
12344 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12345 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
12346 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12347 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12348 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000},
12351 static const DWORD ps_code[] =
12353 0xffff0200, /* ps_2_0 */
12354 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
12355 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
12356 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
12357 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
12358 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
12359 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
12360 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
12361 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
12362 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
12363 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
12364 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
12365 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
12366 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
12367 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
12368 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
12369 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
12370 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
12371 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
12372 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
12373 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
12374 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
12375 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12376 0x0000ffff, /* end */
12379 struct
12381 float x, y, z;
12382 float s;
12384 quad[] =
12386 { -1.0f, 1.0f, 0.0f, 0.0f},
12387 { 1.0f, 1.0f, 1.0f, 0.0f},
12388 { -1.0f, -1.0f, 0.0f, 0.0f},
12389 { 1.0f, -1.0f, 1.0f, 0.0f},
12392 IDirect3DPixelShader9 *ps;
12393 UINT body_size = 0;
12394 DWORD *vs_code;
12395 D3DCAPS9 caps;
12396 HRESULT hr;
12397 UINT i;
12399 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12400 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12401 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12403 skip("No shader model 2.0 support, skipping floating point specials test.\n");
12404 return;
12407 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12408 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12410 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12411 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12412 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12413 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12416 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12419 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12421 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12423 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12426 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12427 memcpy(vs_code, vs_header, sizeof(vs_header));
12429 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12431 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12432 IDirect3DVertexShader9 *vs;
12433 D3DCOLOR color;
12435 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12436 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12437 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12439 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12440 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12441 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12442 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12444 hr = IDirect3DDevice9_BeginScene(device);
12445 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12447 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12448 hr = IDirect3DDevice9_EndScene(device);
12449 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12451 color = getPixelColor(device, 320, 240);
12452 ok(color_match(color, vs_body[i].r600, 1)
12453 || color_match(color, vs_body[i].nv40, 1)
12454 || color_match(color, vs_body[i].nv50, 1),
12455 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12456 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12458 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12459 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12461 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12462 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12463 IDirect3DVertexShader9_Release(vs);
12466 HeapFree(GetProcessHeap(), 0, vs_code);
12468 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12469 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12470 IDirect3DPixelShader9_Release(ps);
12473 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12475 IDirect3D9 *d3d;
12476 IDirect3DSurface9 *rt, *backbuffer;
12477 IDirect3DTexture9 *texture;
12478 HRESULT hr;
12479 int i;
12480 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12481 static const struct
12483 D3DFORMAT fmt;
12484 const char *name;
12486 formats[] =
12488 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12489 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12490 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12491 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12492 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12494 static const struct
12496 float x, y, z;
12497 float u, v;
12499 quad[] =
12501 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12502 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12503 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12504 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12507 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12508 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12509 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12510 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12511 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12512 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12513 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12514 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12516 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12518 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12520 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12521 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12523 skip("Format %s not supported as render target, skipping test.\n",
12524 formats[i].name);
12525 continue;
12528 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12529 D3DPOOL_DEFAULT, &texture, NULL);
12530 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12532 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12534 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12535 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12536 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12537 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12539 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12541 hr = IDirect3DDevice9_BeginScene(device);
12542 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12543 if(SUCCEEDED(hr))
12545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12546 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12547 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12548 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12550 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12553 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12554 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12555 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12556 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12557 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12558 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12559 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12561 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12562 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12563 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12565 hr = IDirect3DDevice9_EndScene(device);
12566 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12569 IDirect3DSurface9_Release(rt);
12570 IDirect3DTexture9_Release(texture);
12572 color = getPixelColor(device, 360, 240);
12573 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12574 D3DUSAGE_QUERY_SRGBWRITE,
12575 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12577 /* Big slop for R5G6B5 */
12578 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12579 formats[i].name, color_srgb, color);
12581 else
12583 /* Big slop for R5G6B5 */
12584 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12585 formats[i].name, color_rgb, color);
12588 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12589 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12592 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12593 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12595 IDirect3D9_Release(d3d);
12596 IDirect3DSurface9_Release(backbuffer);
12599 static void ds_size_test(IDirect3DDevice9 *device)
12601 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12602 HRESULT hr;
12603 DWORD num_passes;
12604 struct
12606 float x, y, z;
12608 quad[] =
12610 {-1.0, -1.0, 0.0 },
12611 {-1.0, 1.0, 0.0 },
12612 { 1.0, -1.0, 0.0 },
12613 { 1.0, 1.0, 0.0 }
12616 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12617 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12618 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12619 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12620 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12621 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12624 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12626 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12628 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12629 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12630 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12631 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12632 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12633 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12634 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12635 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12636 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12637 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12638 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12639 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12640 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12642 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12643 * but does not change the surface's contents. */
12644 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12645 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12647 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12649 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12651 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12653 /* Turning on any depth-related state results in a ValidateDevice failure */
12654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12655 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12656 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12657 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12658 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12660 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12662 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12663 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12664 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12665 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12667 /* Try to draw with the device in an invalid state */
12668 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12669 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12670 hr = IDirect3DDevice9_BeginScene(device);
12671 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12672 if(SUCCEEDED(hr))
12674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12675 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12676 hr = IDirect3DDevice9_EndScene(device);
12677 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12679 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12680 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12681 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12684 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12685 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12686 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12687 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12688 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12689 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12691 IDirect3DSurface9_Release(readback);
12692 IDirect3DSurface9_Release(ds);
12693 IDirect3DSurface9_Release(rt);
12694 IDirect3DSurface9_Release(old_rt);
12695 IDirect3DSurface9_Release(old_ds);
12698 static void unbound_sampler_test(IDirect3DDevice9 *device)
12700 HRESULT hr;
12701 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12702 IDirect3DSurface9 *rt, *old_rt;
12703 DWORD color;
12705 static const DWORD ps_code[] =
12707 0xffff0200, /* ps_2_0 */
12708 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12709 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12710 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12711 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12712 0x0000ffff, /* end */
12714 static const DWORD ps_code_cube[] =
12716 0xffff0200, /* ps_2_0 */
12717 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
12718 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12719 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12720 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12721 0x0000ffff, /* end */
12723 static const DWORD ps_code_volume[] =
12725 0xffff0200, /* ps_2_0 */
12726 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
12727 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12728 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12729 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12730 0x0000ffff, /* end */
12733 static const struct
12735 float x, y, z;
12736 float u, v;
12738 quad[] =
12740 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12741 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12742 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12743 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12746 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12747 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12749 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12750 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12751 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12752 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12753 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12754 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12756 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12757 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12759 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12760 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12762 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12763 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12765 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12766 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12768 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12769 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12771 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12772 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12774 hr = IDirect3DDevice9_BeginScene(device);
12775 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12776 if(SUCCEEDED(hr))
12778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12779 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12781 hr = IDirect3DDevice9_EndScene(device);
12782 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12785 color = getPixelColorFromSurface(rt, 32, 32);
12786 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12788 /* Now try with a cube texture */
12789 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12790 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12792 hr = IDirect3DDevice9_BeginScene(device);
12793 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12794 if (SUCCEEDED(hr))
12796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12797 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12799 hr = IDirect3DDevice9_EndScene(device);
12800 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12803 color = getPixelColorFromSurface(rt, 32, 32);
12804 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12806 /* And then with a volume texture */
12807 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12808 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12810 hr = IDirect3DDevice9_BeginScene(device);
12811 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12812 if (SUCCEEDED(hr))
12814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12815 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12817 hr = IDirect3DDevice9_EndScene(device);
12818 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12821 color = getPixelColorFromSurface(rt, 32, 32);
12822 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12824 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12825 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12827 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12828 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12830 IDirect3DSurface9_Release(rt);
12831 IDirect3DSurface9_Release(old_rt);
12832 IDirect3DPixelShader9_Release(ps);
12833 IDirect3DPixelShader9_Release(ps_cube);
12834 IDirect3DPixelShader9_Release(ps_volume);
12837 static void update_surface_test(IDirect3DDevice9 *device)
12839 static const BYTE blocks[][8] =
12841 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12842 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12843 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12844 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12845 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12846 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12847 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12849 static const struct
12851 UINT x, y;
12852 D3DCOLOR color;
12854 expected_colors[] =
12856 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12857 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12858 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12859 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12860 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12861 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12862 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12864 static const struct
12866 float x, y, z, w;
12867 float u, v;
12869 tri[] =
12871 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12872 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12873 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12875 static const RECT rect_2x2 = {0, 0, 2, 2};
12876 static const struct
12878 UINT src_level;
12879 UINT dst_level;
12880 const RECT *r;
12881 HRESULT hr;
12883 block_size_tests[] =
12885 {1, 0, NULL, D3D_OK},
12886 {0, 1, NULL, D3DERR_INVALIDCALL},
12887 {5, 4, NULL, D3DERR_INVALIDCALL},
12888 {4, 5, NULL, D3DERR_INVALIDCALL},
12889 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12890 {5, 5, &rect_2x2, D3D_OK},
12893 IDirect3DSurface9 *src_surface, *dst_surface;
12894 IDirect3DTexture9 *src_tex, *dst_tex;
12895 IDirect3D9 *d3d;
12896 UINT count, i;
12897 HRESULT hr;
12899 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12900 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12902 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12903 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12904 IDirect3D9_Release(d3d);
12905 if (FAILED(hr))
12907 skip("DXT1 not supported, skipping test.\n");
12908 return;
12911 IDirect3D9_Release(d3d);
12913 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12914 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12915 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12916 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12918 count = IDirect3DTexture9_GetLevelCount(src_tex);
12919 ok(count == 7, "Got level count %u, expected 7.\n", count);
12921 for (i = 0; i < count; ++i)
12923 UINT row_count, block_count, x, y;
12924 D3DSURFACE_DESC desc;
12925 BYTE *row, *block;
12926 D3DLOCKED_RECT r;
12928 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12929 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12931 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12932 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12934 row_count = ((desc.Height + 3) & ~3) / 4;
12935 block_count = ((desc.Width + 3) & ~3) / 4;
12936 row = r.pBits;
12938 for (y = 0; y < row_count; ++y)
12940 block = row;
12941 for (x = 0; x < block_count; ++x)
12943 memcpy(block, blocks[i], sizeof(blocks[i]));
12944 block += sizeof(blocks[i]);
12946 row += r.Pitch;
12949 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12950 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12953 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12955 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12956 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12957 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12958 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12960 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12961 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12962 hr, i, block_size_tests[i].hr);
12964 IDirect3DSurface9_Release(dst_surface);
12965 IDirect3DSurface9_Release(src_surface);
12968 for (i = 0; i < count; ++i)
12970 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12971 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12972 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12973 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12975 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12976 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12978 IDirect3DSurface9_Release(dst_surface);
12979 IDirect3DSurface9_Release(src_surface);
12982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12983 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12984 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12985 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12986 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12987 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12988 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12989 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12990 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12991 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12992 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12993 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12996 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12998 hr = IDirect3DDevice9_BeginScene(device);
12999 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
13001 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13002 hr = IDirect3DDevice9_EndScene(device);
13003 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13005 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13007 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13008 ok(color_match(color, expected_colors[i].color, 0),
13009 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13010 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13013 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13014 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13016 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13017 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13018 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13019 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13020 IDirect3DTexture9_Release(dst_tex);
13021 IDirect3DTexture9_Release(src_tex);
13024 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13026 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13027 IDirect3D9 *d3d9;
13028 HRESULT hr;
13030 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13031 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13032 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13033 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13034 IDirect3D9_Release(d3d9);
13035 if (FAILED(hr))
13037 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13038 return;
13041 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13042 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13043 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13044 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13045 D3DPOOL_SYSTEMMEM, &readback, NULL);
13046 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13048 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13049 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13050 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13051 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13053 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13054 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13055 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13056 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13058 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13059 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13060 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13061 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13063 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13064 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13065 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13066 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13068 IDirect3DSurface9_Release(original_ds);
13069 IDirect3DSurface9_Release(original_rt);
13070 IDirect3DSurface9_Release(readback);
13071 IDirect3DSurface9_Release(rt);
13074 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13076 IDirect3DDevice9 *device = 0;
13077 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13078 D3DCAPS9 caps;
13079 HRESULT hr;
13080 D3DPRESENT_PARAMETERS present_parameters;
13081 unsigned int i;
13082 static const struct
13084 float x, y, z;
13085 D3DCOLOR color;
13087 quad_1[] =
13089 { -1.0f, 1.0f, 0.0f, 0xffff0000},
13090 { 1.0f, 1.0f, 1.0f, 0xffff0000},
13091 { -1.0f, -1.0f, 0.0f, 0xffff0000},
13092 { 1.0f, -1.0f, 1.0f, 0xffff0000},
13094 quad_2[] =
13096 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
13097 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
13098 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13099 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
13101 static const struct
13103 UINT x, y;
13104 D3DCOLOR color;
13106 expected_colors[] =
13108 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13109 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13110 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13111 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13112 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13113 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13114 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13115 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13118 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13119 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13120 if (FAILED(hr))
13122 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13123 return;
13125 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13126 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13127 if (FAILED(hr))
13129 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13130 return;
13133 ZeroMemory(&present_parameters, sizeof(present_parameters));
13134 present_parameters.Windowed = TRUE;
13135 present_parameters.hDeviceWindow = create_window();
13136 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13137 present_parameters.BackBufferWidth = 640;
13138 present_parameters.BackBufferHeight = 480;
13139 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13140 present_parameters.EnableAutoDepthStencil = TRUE;
13141 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13142 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13144 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13145 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13146 &present_parameters, &device);
13147 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13149 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13150 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13151 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13153 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13154 goto cleanup;
13157 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13158 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13159 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13160 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13161 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13162 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13164 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13165 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13166 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13167 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13170 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13172 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13174 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13176 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13177 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13178 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13180 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13181 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13183 /* Render onscreen and then offscreen */
13184 hr = IDirect3DDevice9_BeginScene(device);
13185 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13186 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13187 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13188 hr = IDirect3DDevice9_EndScene(device);
13189 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13191 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13192 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13194 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13196 hr = IDirect3DDevice9_BeginScene(device);
13197 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13199 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13200 hr = IDirect3DDevice9_EndScene(device);
13201 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13203 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13204 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13206 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13208 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13209 ok(color_match(color, expected_colors[i].color, 1),
13210 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13211 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13214 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13215 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13216 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13217 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13219 /* Render offscreen and then onscreen */
13220 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13221 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13222 IDirect3DSurface9_Release(ds);
13223 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13224 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13225 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13226 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13228 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13229 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13231 hr = IDirect3DDevice9_BeginScene(device);
13232 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13234 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13235 hr = IDirect3DDevice9_EndScene(device);
13236 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13238 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13239 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13240 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13241 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13243 hr = IDirect3DDevice9_BeginScene(device);
13244 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13246 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13247 hr = IDirect3DDevice9_EndScene(device);
13248 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13250 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13251 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13253 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13255 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13256 ok(color_match(color, expected_colors[i].color, 1),
13257 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13258 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13261 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13262 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13264 IDirect3DSurface9_Release(ds);
13265 IDirect3DSurface9_Release(readback);
13266 IDirect3DSurface9_Release(rt);
13267 IDirect3DSurface9_Release(original_rt);
13268 cleanup_device(device);
13270 ZeroMemory(&present_parameters, sizeof(present_parameters));
13271 present_parameters.Windowed = TRUE;
13272 present_parameters.hDeviceWindow = create_window();
13273 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13274 present_parameters.BackBufferWidth = 640;
13275 present_parameters.BackBufferHeight = 480;
13276 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13277 present_parameters.EnableAutoDepthStencil = TRUE;
13278 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13279 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13281 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13282 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13283 &present_parameters, &device);
13284 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13286 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13287 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13289 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13290 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13291 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13292 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13293 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13294 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13295 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13296 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13297 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13299 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13300 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13301 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13302 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13303 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13304 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13305 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13306 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13309 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13310 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13311 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13313 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13315 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13316 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13317 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13319 /* Render to a multisampled offscreen frame buffer and then blit to
13320 * the onscreen (not multisampled) frame buffer. */
13321 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13322 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13324 hr = IDirect3DDevice9_BeginScene(device);
13325 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13328 hr = IDirect3DDevice9_EndScene(device);
13329 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13331 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13332 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13333 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13334 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13336 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13337 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13338 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13339 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13341 hr = IDirect3DDevice9_BeginScene(device);
13342 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13344 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13345 hr = IDirect3DDevice9_EndScene(device);
13346 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13348 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13349 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13351 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13353 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13354 if (i % 4 < 2)
13355 todo_wine ok(color_match(color, expected_colors[i].color, 1),
13356 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13357 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13358 else
13359 ok(color_match(color, expected_colors[i].color, 1),
13360 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13361 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13364 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13365 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13367 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13368 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13369 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13370 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13372 IDirect3DSurface9_Release(original_ds);
13373 IDirect3DSurface9_Release(original_rt);
13374 IDirect3DSurface9_Release(ds);
13375 IDirect3DSurface9_Release(readback);
13376 IDirect3DSurface9_Release(rt);
13377 cleanup:
13378 cleanup_device(device);
13381 static void resz_test(IDirect3D9 *d3d9)
13383 IDirect3DDevice9 *device = 0;
13384 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13385 D3DCAPS9 caps;
13386 HRESULT hr;
13387 D3DPRESENT_PARAMETERS present_parameters;
13388 unsigned int i;
13389 static const DWORD ps_code[] =
13391 0xffff0200, /* ps_2_0 */
13392 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13393 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13394 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13395 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13396 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13397 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13398 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13399 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13400 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13401 0x0000ffff, /* end */
13403 struct
13405 float x, y, z;
13406 float s, t, p, q;
13408 quad[] =
13410 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13411 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13412 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13413 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13415 struct
13417 UINT x, y;
13418 D3DCOLOR color;
13420 expected_colors[] =
13422 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13423 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13424 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13425 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13426 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13427 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13428 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13429 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13431 IDirect3DTexture9 *texture;
13432 IDirect3DPixelShader9 *ps;
13433 DWORD value;
13435 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13436 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13437 if (FAILED(hr))
13439 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13440 return;
13442 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13443 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13444 if (FAILED(hr))
13446 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13447 return;
13450 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13451 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13452 if (FAILED(hr))
13454 skip("No INTZ support, skipping RESZ test.\n");
13455 return;
13458 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13459 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13460 if (FAILED(hr))
13462 skip("No RESZ support, skipping RESZ test.\n");
13463 return;
13466 ZeroMemory(&present_parameters, sizeof(present_parameters));
13467 present_parameters.Windowed = TRUE;
13468 present_parameters.hDeviceWindow = create_window();
13469 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13470 present_parameters.BackBufferWidth = 640;
13471 present_parameters.BackBufferHeight = 480;
13472 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13473 present_parameters.EnableAutoDepthStencil = FALSE;
13474 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13475 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13477 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13478 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13479 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13481 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13482 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13483 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13485 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13486 cleanup_device(device);
13487 return;
13489 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13491 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13492 cleanup_device(device);
13493 return;
13496 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13497 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13499 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13500 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13501 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13502 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13503 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13504 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13505 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13506 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13508 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13509 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13510 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13511 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13512 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13513 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13514 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13516 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13517 IDirect3DSurface9_Release(intz_ds);
13518 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13519 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13521 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13522 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13523 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13524 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13525 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13526 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13528 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13530 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13532 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13533 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13534 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13535 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13536 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13537 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13539 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13540 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13541 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13543 /* Render offscreen (multisampled), blit the depth buffer
13544 * into the INTZ texture and then check its contents */
13545 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13546 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13547 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13548 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13550 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13552 hr = IDirect3DDevice9_BeginScene(device);
13553 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13555 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13557 /* The destination depth texture has to be bound to sampler 0 */
13558 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13559 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13561 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13563 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13564 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13565 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13567 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13569 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13571 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13573 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13575 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13577 /* The actual multisampled depth buffer resolve happens here */
13578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13579 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13580 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13581 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13583 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13584 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13585 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13586 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13588 /* Read the depth values back */
13589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13590 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13591 hr = IDirect3DDevice9_EndScene(device);
13592 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13594 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13596 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13597 ok(color_match(color, expected_colors[i].color, 1),
13598 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13599 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13602 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13603 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13605 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13606 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13607 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13608 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13609 IDirect3DSurface9_Release(ds);
13610 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13611 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13612 IDirect3DTexture9_Release(texture);
13613 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13614 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13615 IDirect3DPixelShader9_Release(ps);
13616 IDirect3DSurface9_Release(readback);
13617 IDirect3DSurface9_Release(original_rt);
13618 IDirect3DSurface9_Release(rt);
13619 cleanup_device(device);
13622 ZeroMemory(&present_parameters, sizeof(present_parameters));
13623 present_parameters.Windowed = TRUE;
13624 present_parameters.hDeviceWindow = create_window();
13625 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13626 present_parameters.BackBufferWidth = 640;
13627 present_parameters.BackBufferHeight = 480;
13628 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13629 present_parameters.EnableAutoDepthStencil = TRUE;
13630 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13631 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13633 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13634 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13635 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13637 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13638 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13639 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13640 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13641 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13642 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13643 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13644 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13645 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13646 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13647 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13648 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13649 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13650 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13651 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13652 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13654 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13655 IDirect3DSurface9_Release(intz_ds);
13656 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13657 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13659 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13660 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13662 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13664 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13666 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13668 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13670 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13671 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13672 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13673 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13674 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13675 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13676 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13677 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13678 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13679 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13681 /* Render onscreen, blit the depth buffer into the INTZ texture
13682 * and then check its contents */
13683 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13684 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13685 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13686 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13687 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13688 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13690 hr = IDirect3DDevice9_BeginScene(device);
13691 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13693 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13694 hr = IDirect3DDevice9_EndScene(device);
13695 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13697 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13698 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13701 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13703 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13705 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13707 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13709 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13711 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13713 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13715 /* The actual multisampled depth buffer resolve happens here */
13716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13717 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13718 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13719 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13721 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13722 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13723 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13724 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13726 /* Read the depth values back */
13727 hr = IDirect3DDevice9_BeginScene(device);
13728 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13730 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13731 hr = IDirect3DDevice9_EndScene(device);
13732 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13734 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13736 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13737 ok(color_match(color, expected_colors[i].color, 1),
13738 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13739 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13743 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13746 /* Test edge cases - try with no texture at all */
13747 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13748 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13749 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13750 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13752 hr = IDirect3DDevice9_BeginScene(device);
13753 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13755 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13756 hr = IDirect3DDevice9_EndScene(device);
13757 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13760 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13762 /* With a non-multisampled depth buffer */
13763 IDirect3DSurface9_Release(ds);
13764 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13765 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13767 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13768 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13769 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13770 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13771 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13772 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13774 hr = IDirect3DDevice9_BeginScene(device);
13775 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13777 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13779 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13780 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13783 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13785 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13787 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13789 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13791 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13793 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13795 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13796 hr = IDirect3DDevice9_EndScene(device);
13797 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13800 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13802 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13803 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13805 /* Read the depth values back. */
13806 hr = IDirect3DDevice9_BeginScene(device);
13807 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13809 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13810 hr = IDirect3DDevice9_EndScene(device);
13811 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13813 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13815 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13816 ok(color_match(color, expected_colors[i].color, 1),
13817 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13818 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13821 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13822 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13824 /* Without a current depth-stencil buffer set */
13825 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13826 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13827 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13828 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13830 hr = IDirect3DDevice9_BeginScene(device);
13831 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13833 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13834 hr = IDirect3DDevice9_EndScene(device);
13835 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13838 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13840 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13841 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13842 IDirect3DSurface9_Release(ds);
13843 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13844 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13845 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13846 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13847 IDirect3DTexture9_Release(texture);
13848 IDirect3DPixelShader9_Release(ps);
13849 IDirect3DSurface9_Release(readback);
13850 IDirect3DSurface9_Release(original_rt);
13851 cleanup_device(device);
13854 static void zenable_test(IDirect3DDevice9 *device)
13856 static const struct
13858 struct vec4 position;
13859 D3DCOLOR diffuse;
13861 tquad[] =
13863 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13864 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
13865 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
13866 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
13868 D3DCOLOR color;
13869 D3DCAPS9 caps;
13870 HRESULT hr;
13871 UINT x, y;
13872 UINT i, j;
13874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13875 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13876 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13877 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13880 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13881 hr = IDirect3DDevice9_BeginScene(device);
13882 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13884 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13885 hr = IDirect3DDevice9_EndScene(device);
13886 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13888 for (i = 0; i < 4; ++i)
13890 for (j = 0; j < 4; ++j)
13892 x = 80 * ((2 * j) + 1);
13893 y = 60 * ((2 * i) + 1);
13894 color = getPixelColor(device, x, y);
13895 ok(color_match(color, 0x0000ff00, 1),
13896 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13900 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13901 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13903 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13904 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13906 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13907 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13909 static const DWORD vs_code[] =
13911 0xfffe0101, /* vs_1_1 */
13912 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13913 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13914 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
13915 0x0000ffff
13917 static const DWORD ps_code[] =
13919 0xffff0101, /* ps_1_1 */
13920 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
13921 0x0000ffff /* end */
13923 static const struct vec3 quad[] =
13925 {-1.0f, -1.0f, -0.5f},
13926 {-1.0f, 1.0f, -0.5f},
13927 { 1.0f, -1.0f, 1.5f},
13928 { 1.0f, 1.0f, 1.5f},
13930 static const D3DCOLOR expected[] =
13932 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13933 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13934 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13935 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13938 IDirect3DVertexShader9 *vs;
13939 IDirect3DPixelShader9 *ps;
13941 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13942 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13943 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13944 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13945 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13946 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13947 hr = IDirect3DDevice9_SetVertexShader(device, vs);
13948 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13949 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13950 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13953 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13954 hr = IDirect3DDevice9_BeginScene(device);
13955 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13957 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13958 hr = IDirect3DDevice9_EndScene(device);
13959 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13961 for (i = 0; i < 4; ++i)
13963 for (j = 0; j < 4; ++j)
13965 x = 80 * ((2 * j) + 1);
13966 y = 60 * ((2 * i) + 1);
13967 color = getPixelColor(device, x, y);
13968 ok(color_match(color, expected[i * 4 + j], 1),
13969 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13974 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13976 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13977 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13978 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13979 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13980 IDirect3DPixelShader9_Release(ps);
13981 IDirect3DVertexShader9_Release(vs);
13985 START_TEST(visual)
13987 IDirect3D9 *d3d9;
13988 IDirect3DDevice9 *device_ptr;
13989 D3DCAPS9 caps;
13990 HRESULT hr;
13991 DWORD color;
13993 d3d9_handle = LoadLibraryA("d3d9.dll");
13994 if (!d3d9_handle)
13996 skip("Could not load d3d9.dll\n");
13997 return;
14000 device_ptr = init_d3d9();
14001 if (!device_ptr)
14003 skip("Creating the device failed\n");
14004 return;
14007 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14009 /* Check for the reliability of the returned data */
14010 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14011 if(FAILED(hr))
14013 skip("Clear failed, can't assure correctness of the test results, skipping\n");
14014 goto cleanup;
14017 color = getPixelColor(device_ptr, 1, 1);
14018 if(color !=0x00ff0000)
14020 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14021 goto cleanup;
14023 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14025 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14026 if(FAILED(hr))
14028 skip("Clear failed, can't assure correctness of the test results, skipping\n");
14029 goto cleanup;
14032 color = getPixelColor(device_ptr, 639, 479);
14033 if(color != 0x0000ddee)
14035 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14036 goto cleanup;
14038 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14040 /* Now execute the real tests */
14041 depth_clamp_test(device_ptr);
14042 stretchrect_test(device_ptr);
14043 lighting_test(device_ptr);
14044 clear_test(device_ptr);
14045 color_fill_test(device_ptr);
14046 fog_test(device_ptr);
14047 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14049 test_cube_wrap(device_ptr);
14050 } else {
14051 skip("No cube texture support\n");
14053 z_range_test(device_ptr);
14054 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14056 maxmip_test(device_ptr);
14058 else
14060 skip("No mipmap support\n");
14062 offscreen_test(device_ptr);
14063 ds_size_test(device_ptr);
14064 alpha_test(device_ptr);
14065 shademode_test(device_ptr);
14066 srgbtexture_test(device_ptr);
14067 release_buffer_test(device_ptr);
14068 float_texture_test(device_ptr);
14069 g16r16_texture_test(device_ptr);
14070 pixelshader_blending_test(device_ptr);
14071 texture_transform_flags_test(device_ptr);
14072 autogen_mipmap_test(device_ptr);
14073 fixed_function_decl_test(device_ptr);
14074 conditional_np2_repeat_test(device_ptr);
14075 fixed_function_bumpmap_test(device_ptr);
14076 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14077 stencil_cull_test(device_ptr);
14078 } else {
14079 skip("No two sided stencil support\n");
14081 pointsize_test(device_ptr);
14082 tssargtemp_test(device_ptr);
14083 np2_stretch_rect_test(device_ptr);
14084 yuv_color_test(device_ptr);
14085 zwriteenable_test(device_ptr);
14086 alphatest_test(device_ptr);
14087 viewport_test(device_ptr);
14089 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14091 test_constant_clamp_vs(device_ptr);
14092 test_compare_instructions(device_ptr);
14094 else skip("No vs_1_1 support\n");
14096 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14098 test_mova(device_ptr);
14099 loop_index_test(device_ptr);
14100 sincos_test(device_ptr);
14101 sgn_test(device_ptr);
14102 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14103 test_vshader_input(device_ptr);
14104 test_vshader_float16(device_ptr);
14105 stream_test(device_ptr);
14106 } else {
14107 skip("No vs_3_0 support\n");
14110 else skip("No vs_2_0 support\n");
14112 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14114 fog_with_shader_test(device_ptr);
14116 else skip("No vs_2_0 and ps_2_0 support\n");
14118 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14120 texbem_test(device_ptr);
14121 texdepth_test(device_ptr);
14122 texkill_test(device_ptr);
14123 x8l8v8u8_test(device_ptr);
14124 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14125 constant_clamp_ps_test(device_ptr);
14126 cnd_test(device_ptr);
14127 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14128 dp2add_ps_test(device_ptr);
14129 unbound_sampler_test(device_ptr);
14130 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14131 nested_loop_test(device_ptr);
14132 pretransformed_varying_test(device_ptr);
14133 vFace_register_test(device_ptr);
14134 vpos_register_test(device_ptr);
14135 multiple_rendertargets_test(device_ptr);
14136 } else {
14137 skip("No ps_3_0 or vs_3_0 support\n");
14139 } else {
14140 skip("No ps_2_0 support\n");
14144 else skip("No ps_1_1 support\n");
14146 texop_test(device_ptr);
14147 texop_range_test(device_ptr);
14148 alphareplicate_test(device_ptr);
14149 dp3_alpha_test(device_ptr);
14150 depth_buffer_test(device_ptr);
14151 depth_buffer2_test(device_ptr);
14152 depth_blit_test(device_ptr);
14153 intz_test(device_ptr);
14154 shadow_test(device_ptr);
14155 fp_special_test(device_ptr);
14156 depth_bounds_test(device_ptr);
14157 srgbwrite_format_test(device_ptr);
14158 clip_planes_test(device_ptr);
14159 update_surface_test(device_ptr);
14160 multisample_get_rtdata_test(device_ptr);
14161 zenable_test(device_ptr);
14163 hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14164 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14165 cleanup_device(device_ptr);
14166 device_ptr = NULL;
14168 multisampled_depth_buffer_test(d3d9);
14169 resz_test(d3d9);
14171 IDirect3D9_Release(d3d9);
14173 cleanup:
14174 cleanup_device(device_ptr);