2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
24 #include "wine/test.h"
26 static HMODULE d3d8_handle = 0;
28 static HWND create_window(void)
32 wc.lpfnWndProc = DefWindowProc;
33 wc.lpszClassName = "d3d8_test_wc";
36 ret = CreateWindow("d3d8_test_wc", "d3d8_test",
37 WS_POPUP | WS_SYSMENU , 20, 20, 640, 480, 0, 0, 0, 0);
38 ShowWindow(ret, SW_SHOW);
42 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
44 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
46 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
48 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
57 IDirect3DTexture8 *tex = NULL;
58 IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
60 D3DLOCKED_RECT lockedRect;
61 RECT rectToLock = {x, y, x+1, y+1};
63 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
64 if(FAILED(hr) || !tex ) /* This is not a test */
66 trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr);
69 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &surf);
70 if(FAILED(hr) || !tex ) /* This is not a test */
72 trace("Can't get surface from texture, hr=%#08x\n", hr);
77 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
80 trace("Can't get the render target, hr=%#08x\n", hr);
84 hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
87 trace("Can't read the render target, hr=%#08x\n", hr);
92 hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
95 trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
99 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
100 * really important for these tests
102 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
103 hr = IDirect3DSurface8_UnlockRect(surf);
106 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
110 if(backbuf) IDirect3DSurface8_Release(backbuf);
111 if(surf) IDirect3DSurface8_Release(surf);
112 if(tex) IDirect3DTexture8_Release(tex);
116 static IDirect3DDevice8 *init_d3d8(void)
118 IDirect3D8 * (__stdcall * d3d8_create)(UINT SDKVersion) = 0;
119 IDirect3D8 *d3d8_ptr = 0;
120 IDirect3DDevice8 *device_ptr = 0;
121 D3DPRESENT_PARAMETERS present_parameters;
124 d3d8_create = (void *)GetProcAddress(d3d8_handle, "Direct3DCreate8");
125 ok(d3d8_create != NULL, "Failed to get address of Direct3DCreate8\n");
126 if (!d3d8_create) return NULL;
128 d3d8_ptr = d3d8_create(D3D_SDK_VERSION);
131 skip("could not create D3D8\n");
135 ZeroMemory(&present_parameters, sizeof(present_parameters));
136 present_parameters.Windowed = TRUE;
137 present_parameters.hDeviceWindow = create_window();
138 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
139 present_parameters.BackBufferWidth = 640;
140 present_parameters.BackBufferHeight = 480;
141 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
142 present_parameters.EnableAutoDepthStencil = TRUE;
143 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
145 hr = IDirect3D8_CreateDevice(d3d8_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
146 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
147 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL || broken(hr == D3DERR_NOTAVAILABLE), "IDirect3D_CreateDevice returned: %#08x\n", hr);
171 static void lighting_test(IDirect3DDevice8 *device)
174 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
175 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
178 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
179 0.0f, 1.0f, 0.0f, 0.0f,
180 0.0f, 0.0f, 1.0f, 0.0f,
181 0.0f, 0.0f, 0.0f, 1.0f };
183 struct vertex unlitquad[] =
185 {-1.0f, -1.0f, 0.1f, 0xffff0000},
186 {-1.0f, 0.0f, 0.1f, 0xffff0000},
187 { 0.0f, 0.0f, 0.1f, 0xffff0000},
188 { 0.0f, -1.0f, 0.1f, 0xffff0000},
190 struct vertex litquad[] =
192 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
193 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
194 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
195 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
197 struct nvertex unlitnquad[] =
199 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
200 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
201 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
202 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
204 struct nvertex litnquad[] =
206 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
207 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
208 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
209 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
211 WORD Indices[] = {0, 1, 2, 2, 3, 0};
213 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
214 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
216 /* Setup some states that may cause issues */
217 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
218 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
219 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
220 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
221 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
222 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
223 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
224 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
225 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
226 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
227 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
228 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
229 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
230 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
231 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
232 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
233 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
234 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
235 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
236 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
237 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
238 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
240 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
241 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
243 hr = IDirect3DDevice8_BeginScene(device);
244 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr);
247 /* No lights are defined... That means, lit vertices should be entirely black */
248 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
249 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
250 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
251 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
252 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
254 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
255 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
256 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
257 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
258 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
260 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
261 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed with %#08x\n", hr);
263 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
264 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
265 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
266 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
267 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
269 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
270 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
271 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
272 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
273 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
275 IDirect3DDevice8_EndScene(device);
276 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %#08x\n", hr);
279 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
280 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
281 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
282 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
283 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
284 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
285 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
286 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
288 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
290 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
291 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
294 static void clear_test(IDirect3DDevice8 *device)
296 /* Tests the correctness of clearing parameters */
302 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
305 /* Positive x, negative y */
311 /* Positive x, positive y */
316 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
317 * is ignored, the positive is still cleared afterwards
319 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
320 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
322 /* negative x, negative y */
323 rect_negneg.x1 = 640;
324 rect_negneg.y1 = 240;
325 rect_negneg.x2 = 320;
327 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
328 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
330 color = getPixelColor(device, 160, 360); /* lower left quad */
331 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
332 color = getPixelColor(device, 160, 120); /* upper left quad */
333 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
334 color = getPixelColor(device, 480, 360); /* lower right quad */
335 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
336 color = getPixelColor(device, 480, 120); /* upper right quad */
337 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
339 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
354 static void fog_test(IDirect3DDevice8 *device)
358 float start = 0.0, end = 1.0;
360 /* Gets full z based fog with linear fog, no fog with specular color */
361 struct sVertex untransformed_1[] = {
362 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
363 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
364 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
365 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
367 /* Ok, I am too lazy to deal with transform matrices */
368 struct sVertex untransformed_2[] = {
369 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
370 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
371 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
372 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
374 /* Untransformed ones. Give them a different diffuse color to make the test look
375 * nicer. It also makes making sure that they are drawn correctly easier.
377 struct sVertexT transformed_1[] = {
378 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
379 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
380 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
381 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
383 struct sVertexT transformed_2[] = {
384 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
385 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
386 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
387 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
389 WORD Indices[] = {0, 1, 2, 2, 3, 0};
392 float ident_mat[16] =
394 1.0f, 0.0f, 0.0f, 0.0f,
395 0.0f, 1.0f, 0.0f, 0.0f,
396 0.0f, 0.0f, 1.0f, 0.0f,
397 0.0f, 0.0f, 0.0f, 1.0f
399 float world_mat1[16] =
401 1.0f, 0.0f, 0.0f, 0.0f,
402 0.0f, 1.0f, 0.0f, 0.0f,
403 0.0f, 0.0f, 1.0f, 0.0f,
404 0.0f, 0.0f, -0.5f, 1.0f
406 float world_mat2[16] =
408 1.0f, 0.0f, 0.0f, 0.0f,
409 0.0f, 1.0f, 0.0f, 0.0f,
410 0.0f, 0.0f, 1.0f, 0.0f,
411 0.0f, 0.0f, 1.0f, 1.0f
415 1.0f, 0.0f, 0.0f, 0.0f,
416 0.0f, 1.0f, 0.0f, 0.0f,
417 0.0f, 0.0f, 1.0f, 0.0f,
418 0.0f, 0.0f, -1.0f, 1.0f
421 struct sVertex far_quad1[] =
423 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
424 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
425 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
426 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
428 struct sVertex far_quad2[] =
430 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
431 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
432 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
433 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
436 memset(&caps, 0, sizeof(caps));
437 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
438 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
440 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
441 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
443 /* Setup initial states: No lighting, fog on, fog color */
444 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
445 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
446 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
447 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
448 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
449 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
451 /* First test: Both table fog and vertex fog off */
452 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
453 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
454 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
455 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
457 /* Start = 0, end = 1. Should be default, but set them */
458 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
459 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
460 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
461 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
463 if(IDirect3DDevice8_BeginScene(device) == D3D_OK)
465 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
466 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
467 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
468 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
469 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
470 sizeof(untransformed_1[0]));
471 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
473 /* That makes it use the Z value */
474 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
475 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
476 /* Untransformed, vertex fog != none (or table fog != none):
477 * Use the Z value as input into the equation
479 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
480 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
481 sizeof(untransformed_2[0]));
482 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
484 /* transformed verts */
485 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
486 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
487 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
488 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
489 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
490 sizeof(transformed_1[0]));
491 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
493 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
494 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
495 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
498 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
499 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
500 sizeof(transformed_2[0]));
501 ok(SUCCEEDED(hr), "IDirect3DDevice8_DrawIndexedPrimitiveUP returned %#x.\n", hr);
503 hr = IDirect3DDevice8_EndScene(device);
504 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
508 ok(FALSE, "BeginScene failed\n");
511 color = getPixelColor(device, 160, 360);
512 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
513 color = getPixelColor(device, 160, 120);
514 ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
515 color = getPixelColor(device, 480, 120);
516 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
517 color = getPixelColor(device, 480, 360);
518 ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
520 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
522 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
524 /* A simple fog + non-identity world matrix test */
525 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat1);
526 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
528 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
529 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
530 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
531 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
533 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
534 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
536 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
538 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
539 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
541 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
542 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
543 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
545 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
546 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
547 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
549 hr = IDirect3DDevice8_EndScene(device);
550 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
554 ok(FALSE, "BeginScene failed\n");
557 color = getPixelColor(device, 160, 360);
558 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
559 color = getPixelColor(device, 160, 120);
560 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
562 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
564 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
565 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat2);
566 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
567 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) proj_mat);
568 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
570 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
571 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
573 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
575 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
576 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
578 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
579 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
580 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
582 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
583 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
584 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
586 hr = IDirect3DDevice8_EndScene(device);
587 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
591 ok(FALSE, "BeginScene failed\n");
594 color = getPixelColor(device, 160, 360);
595 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
596 color = getPixelColor(device, 160, 120);
597 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
599 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
601 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) ident_mat);
602 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
603 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) ident_mat);
604 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
608 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
611 /* Turn off the fog master switch to avoid confusing other tests */
612 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
613 ok(hr == D3D_OK, "Turning off fog calculations returned %#08x\n", hr);
616 static void present_test(IDirect3DDevice8 *device)
618 struct vertex quad[] =
620 {-1.0f, -1.0f, 0.9f, 0xffff0000},
621 {-1.0f, 1.0f, 0.9f, 0xffff0000},
622 { 1.0f, -1.0f, 0.1f, 0xffff0000},
623 { 1.0f, 1.0f, 0.1f, 0xffff0000},
628 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
629 * then call Present. Then clear the color buffer to make sure it has some defined content
630 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
631 * by the depth value.
633 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
634 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
635 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
636 ok(SUCCEEDED(hr), "IDirect3DDevice8_Present returned %#x.\n", hr);
637 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4f, 0);
638 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear returned %#x.\n", hr);
640 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
641 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
642 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
643 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
644 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
645 ok(hr == D3D_OK, "IDirect3DDevice8_SetFVF returned %08x\n", hr);
647 hr = IDirect3DDevice8_BeginScene(device);
648 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %08x\n", hr);
651 /* No lights are defined... That means, lit vertices should be entirely black */
652 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
653 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %08x\n", hr);
655 hr = IDirect3DDevice8_EndScene(device);
656 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %08x\n", hr);
659 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
660 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
662 color = getPixelColor(device, 512, 240);
663 ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
664 color = getPixelColor(device, 64, 240);
665 ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
667 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
668 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
671 static void test_rcp_rsq(IDirect3DDevice8 *device)
676 float constant[4] = {1.0, 1.0, 1.0, 2.0};
678 static const float quad[][3] = {
679 {-1.0f, -1.0f, 0.0f},
681 { 1.0f, -1.0f, 0.0f},
685 const DWORD rcp_test[] = {
686 0xfffe0101, /* vs.1.1 */
688 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
689 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
690 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
691 0x00303030, /* enough to make windows happy */
693 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
694 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
698 const DWORD rsq_test[] = {
699 0xfffe0101, /* vs.1.1 */
701 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
702 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
703 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
704 0x00303030, /* enough to make windows happy */
706 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
707 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
714 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* D3DVSDE_POSITION, Register v0 */
718 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
719 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
721 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
722 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
724 IDirect3DDevice8_SetVertexShader(device, shader);
725 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
726 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
728 hr = IDirect3DDevice8_BeginScene(device);
729 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
732 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
733 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
734 hr = IDirect3DDevice8_EndScene(device);
735 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
738 color = getPixelColor(device, 320, 240);
739 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), 4),
740 "RCP test returned color 0x%08x, expected 0x00808080.\n", color);
742 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
743 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
745 IDirect3DDevice8_SetVertexShader(device, 0);
746 IDirect3DDevice8_DeleteVertexShader(device, shader);
748 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff996633, 0.0f, 0);
749 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
751 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
752 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
754 IDirect3DDevice8_SetVertexShader(device, shader);
755 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
756 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
758 hr = IDirect3DDevice8_BeginScene(device);
759 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
762 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
763 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
764 hr = IDirect3DDevice8_EndScene(device);
765 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
768 color = getPixelColor(device, 320, 240);
769 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), 4),
770 "RSQ test returned color 0x%08x, expected 0x00b4b4b4.\n", color);
772 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
773 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
775 IDirect3DDevice8_SetVertexShader(device, 0);
776 IDirect3DDevice8_DeleteVertexShader(device, shader);
779 static void offscreen_test(IDirect3DDevice8 *device)
782 IDirect3DTexture8 *offscreenTexture = NULL;
783 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
786 static const float quad[][5] = {
787 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
788 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
789 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
790 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
793 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
794 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
796 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
797 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
799 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
800 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
801 if(!offscreenTexture) {
802 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
803 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
804 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
805 if(!offscreenTexture) {
806 skip("Cannot create an offscreen render target\n");
811 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
812 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
817 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
818 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
823 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
824 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
826 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
827 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
828 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
829 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
830 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
831 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
832 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
833 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
834 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
835 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
837 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
838 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
839 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
840 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
841 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
843 /* Draw without textures - Should result in a white quad */
844 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
845 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
847 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
848 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
849 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
850 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
852 /* This time with the texture */
853 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
854 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
856 IDirect3DDevice8_EndScene(device);
859 /* Center quad - should be white */
860 color = getPixelColor(device, 320, 240);
861 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
862 /* Some quad in the cleared part of the texture */
863 color = getPixelColor(device, 170, 240);
864 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
865 /* Part of the originally cleared back buffer */
866 color = getPixelColor(device, 10, 10);
867 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
869 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
870 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
871 * the offscreen rendering mode this test would succeed or fail
873 color = getPixelColor(device, 10, 470);
874 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
877 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
880 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
881 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetTexture returned %#x.\n", hr);
885 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
886 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetRenderTarget returned %#x.\n", hr);
887 IDirect3DSurface8_Release(backbuffer);
889 if(offscreenTexture) {
890 IDirect3DTexture8_Release(offscreenTexture);
893 IDirect3DSurface8_Release(offscreen);
896 IDirect3DSurface8_Release(depthstencil);
900 static void alpha_test(IDirect3DDevice8 *device)
903 IDirect3DTexture8 *offscreenTexture;
904 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
907 struct vertex quad1[] =
909 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
910 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
911 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
912 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
914 struct vertex quad2[] =
916 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
917 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
918 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
919 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
921 static const float composite_quad[][5] = {
922 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
923 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
924 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
925 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
928 /* Clear the render target with alpha = 0.5 */
929 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
930 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
932 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
933 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
935 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
936 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
938 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
939 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
943 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
944 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
949 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
950 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
952 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
953 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
954 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
955 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
956 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
957 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
958 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
959 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
960 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
961 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
963 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
964 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
965 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
967 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
968 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
969 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
970 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
971 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
972 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
973 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
975 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
976 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
977 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
978 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
979 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
980 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
982 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
983 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
984 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
985 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
986 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
987 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
988 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
990 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
991 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
992 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
993 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
994 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
995 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
997 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
998 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
999 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1000 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1001 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1002 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1004 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1005 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1007 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1008 * Disable alpha blending for the final composition
1010 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1011 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1012 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1013 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1015 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1016 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1017 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
1018 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1019 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1020 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1022 hr = IDirect3DDevice8_EndScene(device);
1023 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1026 color = getPixelColor(device, 160, 360);
1027 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1028 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
1030 color = getPixelColor(device, 160, 120);
1031 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
1032 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
1034 color = getPixelColor(device, 480, 360);
1035 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1036 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
1038 color = getPixelColor(device, 480, 120);
1039 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1040 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
1042 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1045 /* restore things */
1047 IDirect3DSurface8_Release(backbuffer);
1049 if(offscreenTexture) {
1050 IDirect3DTexture8_Release(offscreenTexture);
1053 IDirect3DSurface8_Release(offscreen);
1056 IDirect3DSurface8_Release(depthstencil);
1060 static void p8_texture_test(IDirect3DDevice8 *device)
1062 IDirect3D8 *d3d = NULL;
1064 IDirect3DTexture8 *texture = NULL, *texture2 = NULL;
1066 unsigned char *data;
1067 DWORD color, red, green, blue;
1068 PALETTEENTRY table[256];
1072 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
1073 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
1074 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
1075 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
1078 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
1079 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
1080 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
1081 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
1084 IDirect3DDevice8_GetDirect3D(device, &d3d);
1086 if(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1087 D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK) {
1088 skip("D3DFMT_P8 textures not supported\n");
1092 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1093 D3DPOOL_MANAGED, &texture2);
1094 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1096 skip("Failed to create D3DFMT_P8 texture\n");
1100 memset(&lr, 0, sizeof(lr));
1101 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
1102 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1106 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
1107 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1109 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1110 D3DPOOL_MANAGED, &texture);
1111 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1113 skip("Failed to create D3DFMT_P8 texture\n");
1117 memset(&lr, 0, sizeof(lr));
1118 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
1119 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1123 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1124 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1126 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1127 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1129 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1130 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1132 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
1133 alpha of every entry is set to 1.0, which MS says is required when there's no
1134 D3DPTEXTURECAPS_ALPHAPALETTE capability */
1135 for (i = 0; i < 256; i++) {
1136 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1137 table[i].peFlags = 0xff;
1139 table[1].peRed = 0xff;
1140 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1141 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1144 table[1].peBlue = 0xff;
1145 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1146 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1148 hr = IDirect3DDevice8_BeginScene(device);
1149 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1151 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1152 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1153 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1154 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1156 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1157 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1159 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1160 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1162 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1163 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1164 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1165 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1167 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
1168 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1169 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1170 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1172 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1173 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1174 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1175 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1177 hr = IDirect3DDevice8_EndScene(device);
1178 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1181 color = getPixelColor(device, 32, 32);
1182 red = (color & 0x00ff0000) >> 16;
1183 green = (color & 0x0000ff00) >> 8;
1184 blue = (color & 0x000000ff) >> 0;
1185 ok(red == 0xff && blue == 0 && green == 0,
1186 "got color %08x, expected 0x00ff0000\n", color);
1188 color = getPixelColor(device, 32, 320);
1189 red = (color & 0x00ff0000) >> 16;
1190 green = (color & 0x0000ff00) >> 8;
1191 blue = (color & 0x000000ff) >> 0;
1192 ok(red == 0 && blue == 0xff && green == 0,
1193 "got color %08x, expected 0x000000ff\n", color);
1195 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1196 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1198 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1199 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1201 hr = IDirect3DDevice8_BeginScene(device);
1202 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1204 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1205 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1207 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1208 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1210 hr = IDirect3DDevice8_EndScene(device);
1211 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1215 color = getPixelColor(device, 32, 32);
1216 red = (color & 0x00ff0000) >> 16;
1217 green = (color & 0x0000ff00) >> 8;
1218 blue = (color & 0x000000ff) >> 0;
1219 ok(red == 0 && blue == 0xff && green == 0,
1220 "got color %08x, expected 0x000000ff\n", color);
1222 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1223 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1225 /* Test palettes with alpha */
1226 IDirect3DDevice8_GetDeviceCaps(device, &caps);
1227 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
1228 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
1230 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1231 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1233 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1234 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1236 for (i = 0; i < 256; i++) {
1237 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1238 table[i].peFlags = 0xff;
1240 table[1].peRed = 0xff;
1241 table[1].peFlags = 0x80;
1242 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1243 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1246 table[1].peBlue = 0xff;
1247 table[1].peFlags = 0x80;
1248 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1249 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1251 hr = IDirect3DDevice8_BeginScene(device);
1252 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1254 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1255 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1256 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1257 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1259 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1260 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1262 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1263 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1265 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1266 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1268 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1269 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1271 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1272 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1274 hr = IDirect3DDevice8_EndScene(device);
1275 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1278 color = getPixelColor(device, 32, 32);
1279 red = (color & 0x00ff0000) >> 16;
1280 green = (color & 0x0000ff00) >> 8;
1281 blue = (color & 0x000000ff) >> 0;
1282 ok(red >= 0x7e && red <= 0x81 && blue == 0 && green == 0,
1283 "got color %08x, expected 0x00800000 or near\n", color);
1285 color = getPixelColor(device, 32, 320);
1286 red = (color & 0x00ff0000) >> 16;
1287 green = (color & 0x0000ff00) >> 8;
1288 blue = (color & 0x000000ff) >> 0;
1289 ok(red == 0 && blue >= 0x7e && blue <= 0x81 && green == 0,
1290 "got color %08x, expected 0x00000080 or near\n", color);
1292 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1293 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1296 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1297 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1298 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1299 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1302 if(texture) IDirect3DTexture8_Release(texture);
1303 if(texture2) IDirect3DTexture8_Release(texture2);
1304 IDirect3D8_Release(d3d);
1307 static void texop_test(IDirect3DDevice8 *device)
1309 IDirect3DTexture8 *texture = NULL;
1310 D3DLOCKED_RECT locked_rect;
1316 static const struct {
1321 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
1322 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
1323 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
1324 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
1327 static const struct {
1333 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1334 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
1335 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
1336 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
1337 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1338 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1340 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
1341 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1343 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1344 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1345 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1346 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
1347 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
1348 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1349 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1350 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
1351 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
1352 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1353 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
1354 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
1355 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
1356 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
1357 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
1360 memset(&caps, 0, sizeof(caps));
1361 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1362 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
1364 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
1365 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
1367 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
1368 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
1369 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
1370 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1371 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
1372 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1373 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1374 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1375 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1377 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
1378 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1379 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1380 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1381 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
1382 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1384 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
1385 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1387 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1388 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1389 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
1390 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1391 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
1392 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1394 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1395 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1397 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1399 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
1401 skip("tex operation %s not supported\n", test_data[i].name);
1405 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
1406 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
1408 hr = IDirect3DDevice8_BeginScene(device);
1409 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
1411 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1412 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
1414 hr = IDirect3DDevice8_EndScene(device);
1415 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
1417 color = getPixelColor(device, 320, 240);
1418 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
1419 test_data[i].name, color, test_data[i].result);
1421 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1422 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
1424 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1425 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1428 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1429 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1430 if (texture) IDirect3DTexture8_Release(texture);
1433 /* This test tests depth clamping / clipping behaviour:
1434 * - With software vertex processing, depth values are clamped to the
1435 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
1436 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
1437 * same as regular vertices here.
1438 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
1439 * Normal vertices are always clipped. Pretransformed vertices are
1440 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
1441 * - The viewport's MinZ/MaxZ is irrelevant for this.
1443 static void depth_clamp_test(IDirect3DDevice8 *device)
1445 const struct tvertex quad1[] =
1447 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1448 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1449 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1450 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1452 const struct tvertex quad2[] =
1454 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1455 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1456 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1457 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1459 const struct tvertex quad3[] =
1461 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1462 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1463 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1464 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1466 const struct tvertex quad4[] =
1468 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1469 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1470 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1471 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1473 const struct vertex quad5[] =
1475 { -0.5f, 0.5f, 10.0f, 0xff14f914},
1476 { 0.5f, 0.5f, 10.0f, 0xff14f914},
1477 { -0.5f, -0.5f, 10.0f, 0xff14f914},
1478 { 0.5f, -0.5f, 10.0f, 0xff14f914},
1480 const struct vertex quad6[] =
1482 { -1.0f, 0.5f, 10.0f, 0xfff91414},
1483 { 1.0f, 0.5f, 10.0f, 0xfff91414},
1484 { -1.0f, 0.25f, 10.0f, 0xfff91414},
1485 { 1.0f, 0.25f, 10.0f, 0xfff91414},
1500 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1501 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1503 hr = IDirect3DDevice8_SetViewport(device, &vp);
1504 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1506 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
1507 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1509 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1510 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1511 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1512 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1513 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1514 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1515 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1516 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1518 hr = IDirect3DDevice8_BeginScene(device);
1519 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1521 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1522 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
1524 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1525 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1526 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1527 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1529 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1530 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1532 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1533 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1534 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
1535 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1537 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1538 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1539 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1540 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1542 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
1543 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1545 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1546 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1548 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
1549 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1551 hr = IDirect3DDevice8_EndScene(device);
1552 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1554 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1556 color = getPixelColor(device, 75, 75);
1557 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1558 color = getPixelColor(device, 150, 150);
1559 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1560 color = getPixelColor(device, 320, 240);
1561 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1562 color = getPixelColor(device, 320, 330);
1563 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1564 color = getPixelColor(device, 320, 330);
1565 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1569 color = getPixelColor(device, 75, 75);
1570 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1571 color = getPixelColor(device, 150, 150);
1572 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1573 color = getPixelColor(device, 320, 240);
1574 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
1575 color = getPixelColor(device, 320, 330);
1576 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1577 color = getPixelColor(device, 320, 330);
1578 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1581 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1582 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1586 hr = IDirect3DDevice8_SetViewport(device, &vp);
1587 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1590 static void depth_buffer_test(IDirect3DDevice8 *device)
1592 static const struct vertex quad1[] =
1594 { -1.0, 1.0, 0.33f, 0xff00ff00},
1595 { 1.0, 1.0, 0.33f, 0xff00ff00},
1596 { -1.0, -1.0, 0.33f, 0xff00ff00},
1597 { 1.0, -1.0, 0.33f, 0xff00ff00},
1599 static const struct vertex quad2[] =
1601 { -1.0, 1.0, 0.50f, 0xffff00ff},
1602 { 1.0, 1.0, 0.50f, 0xffff00ff},
1603 { -1.0, -1.0, 0.50f, 0xffff00ff},
1604 { 1.0, -1.0, 0.50f, 0xffff00ff},
1606 static const struct vertex quad3[] =
1608 { -1.0, 1.0, 0.66f, 0xffff0000},
1609 { 1.0, 1.0, 0.66f, 0xffff0000},
1610 { -1.0, -1.0, 0.66f, 0xffff0000},
1611 { 1.0, -1.0, 0.66f, 0xffff0000},
1613 static const DWORD expected_colors[4][4] =
1615 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1616 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1617 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
1618 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
1621 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
1622 IDirect3DSurface8 *depth_stencil;
1635 hr = IDirect3DDevice8_SetViewport(device, &vp);
1636 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1638 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1639 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1640 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1641 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1642 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1643 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1644 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1645 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1646 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1647 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1649 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1650 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1651 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1652 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1653 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
1654 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1655 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1656 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1657 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1658 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1659 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1660 D3DMULTISAMPLE_NONE, FALSE, &rt3);
1661 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1663 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
1664 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1665 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
1666 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1668 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1669 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1670 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1671 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1673 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1674 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1675 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1676 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1678 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1679 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1680 hr = IDirect3DDevice8_BeginScene(device);
1681 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1682 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1683 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1684 hr = IDirect3DDevice8_EndScene(device);
1685 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1687 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1688 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1689 IDirect3DSurface8_Release(depth_stencil);
1690 IDirect3DSurface8_Release(backbuffer);
1691 IDirect3DSurface8_Release(rt3);
1692 IDirect3DSurface8_Release(rt2);
1693 IDirect3DSurface8_Release(rt1);
1695 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1696 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1698 hr = IDirect3DDevice8_BeginScene(device);
1699 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1700 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1701 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1702 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1704 hr = IDirect3DDevice8_EndScene(device);
1705 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1707 for (i = 0; i < 4; ++i)
1709 for (j = 0; j < 4; ++j)
1711 unsigned int x = 80 * ((2 * j) + 1);
1712 unsigned int y = 60 * ((2 * i) + 1);
1713 color = getPixelColor(device, x, y);
1714 ok(color_match(color, expected_colors[i][j], 0),
1715 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
1719 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1720 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1723 /* Test that partial depth copies work the way they're supposed to. The clear
1724 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
1725 * the following draw should only copy back the part that was modified. */
1726 static void depth_buffer2_test(IDirect3DDevice8 *device)
1728 static const struct vertex quad[] =
1730 { -1.0, 1.0, 0.66f, 0xffff0000},
1731 { 1.0, 1.0, 0.66f, 0xffff0000},
1732 { -1.0, -1.0, 0.66f, 0xffff0000},
1733 { 1.0, -1.0, 0.66f, 0xffff0000},
1736 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
1737 IDirect3DSurface8 *depth_stencil;
1750 hr = IDirect3DDevice8_SetViewport(device, &vp);
1751 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1753 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1754 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1755 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1756 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1757 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1758 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1759 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1760 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1761 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1762 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1764 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1765 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1766 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1767 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1768 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1769 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1770 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1771 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1772 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1773 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1775 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1776 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1777 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1778 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1780 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1781 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1782 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
1783 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1785 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1786 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1787 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1788 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1790 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1791 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1792 IDirect3DSurface8_Release(depth_stencil);
1793 IDirect3DSurface8_Release(backbuffer);
1794 IDirect3DSurface8_Release(rt2);
1795 IDirect3DSurface8_Release(rt1);
1797 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1798 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1800 hr = IDirect3DDevice8_BeginScene(device);
1801 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1802 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1803 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1804 hr = IDirect3DDevice8_EndScene(device);
1805 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1807 for (i = 0; i < 4; ++i)
1809 for (j = 0; j < 4; ++j)
1811 unsigned int x = 80 * ((2 * j) + 1);
1812 unsigned int y = 60 * ((2 * i) + 1);
1813 color = getPixelColor(device, x, y);
1814 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
1815 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
1819 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1820 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1823 static void intz_test(IDirect3DDevice8 *device)
1825 static const DWORD ps_code[] =
1827 0xffff0101, /* ps_1_1 */
1828 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
1829 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
1830 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
1831 0x00000042, 0xb00f0000, /* tex t0 */
1832 0x00000042, 0xb00f0001, /* tex t1 */
1833 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
1834 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
1835 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
1836 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
1837 0x0000ffff, /* end */
1843 float s1, t1, p1, q1;
1847 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1848 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1849 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1850 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1859 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
1860 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
1861 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
1862 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
1863 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
1864 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
1865 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
1866 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
1869 IDirect3DSurface8 *original_ds, *original_rt, *rt;
1870 IDirect3DTexture8 *texture;
1871 IDirect3DSurface8 *ds;
1878 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1879 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1880 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1882 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
1886 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
1887 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
1889 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1890 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
1893 skip("No INTZ support, skipping INTZ test.\n");
1897 IDirect3D8_Release(d3d8);
1899 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
1900 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1901 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
1902 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1904 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
1905 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
1906 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
1907 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
1908 D3DMULTISAMPLE_NONE, FALSE, &rt);
1909 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1910 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
1911 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
1913 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
1914 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
1915 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1916 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1918 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
1919 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1920 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1921 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1922 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1923 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1925 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1926 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1927 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
1928 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1929 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1930 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1931 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
1932 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1934 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1935 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1936 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1937 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1938 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1939 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1940 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
1941 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1942 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
1943 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1944 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
1945 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
1946 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1948 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
1949 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
1950 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
1951 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1952 IDirect3DDevice8_SetPixelShader(device, 0);
1953 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
1955 /* Setup the depth/stencil surface. */
1956 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
1957 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1959 hr = IDirect3DDevice8_BeginScene(device);
1960 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1961 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1962 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1963 hr = IDirect3DDevice8_EndScene(device);
1964 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1966 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
1967 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1968 IDirect3DSurface8_Release(ds);
1969 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1970 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
1971 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
1972 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
1973 hr = IDirect3DDevice8_SetPixelShader(device, ps);
1974 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
1976 /* Read the depth values back. */
1977 hr = IDirect3DDevice8_BeginScene(device);
1978 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1979 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1980 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1981 hr = IDirect3DDevice8_EndScene(device);
1982 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1984 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
1986 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
1987 ok(color_match(color, expected_colors[i].color, 1),
1988 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
1989 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
1992 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1993 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
1995 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
1996 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1997 IDirect3DSurface8_Release(original_ds);
1998 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1999 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2000 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2001 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2002 IDirect3DTexture8_Release(texture);
2003 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2004 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2005 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2006 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2008 IDirect3DSurface8_Release(original_rt);
2009 IDirect3DSurface8_Release(rt);
2012 static void shadow_test(IDirect3DDevice8 *device)
2014 static const DWORD ps_code[] =
2016 0xffff0101, /* ps_1_1 */
2017 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2018 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2019 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2020 0x00000042, 0xb00f0000, /* tex t0 */
2021 0x00000042, 0xb00f0001, /* tex t1 */
2022 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2023 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2024 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2025 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2026 0x0000ffff, /* end */
2035 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
2036 {D3DFMT_D32, "D3DFMT_D32"},
2037 {D3DFMT_D15S1, "D3DFMT_D15S1"},
2038 {D3DFMT_D24S8, "D3DFMT_D24S8"},
2039 {D3DFMT_D24X8, "D3DFMT_D24X8"},
2040 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
2041 {D3DFMT_D16, "D3DFMT_D16"},
2047 float s1, t1, p1, q1;
2051 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2052 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2053 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2054 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2063 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2064 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2065 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2066 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2067 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2068 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2069 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2070 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2073 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2080 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2081 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2082 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2084 skip("No pixel shader 1.1 support, skipping shadow test.\n");
2088 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2089 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2090 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2091 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2092 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2093 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2095 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2096 D3DMULTISAMPLE_NONE, FALSE, &rt);
2097 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2098 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2099 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2101 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2102 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2103 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2104 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2105 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2106 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2107 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2108 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2109 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2110 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2111 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2113 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2114 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2115 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2116 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2117 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2118 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2119 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2120 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2122 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2123 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2124 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2125 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2126 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2127 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2128 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2129 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2130 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2131 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2132 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2133 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2134 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2136 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2138 D3DFORMAT format = formats[i].format;
2139 IDirect3DTexture8 *texture;
2140 IDirect3DSurface8 *ds;
2143 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2144 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2145 if (FAILED(hr)) continue;
2147 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2148 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2149 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2151 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2152 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2154 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2155 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2157 IDirect3DDevice8_SetPixelShader(device, 0);
2158 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2160 /* Setup the depth/stencil surface. */
2161 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2162 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2164 hr = IDirect3DDevice8_BeginScene(device);
2165 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2166 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2167 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2168 hr = IDirect3DDevice8_EndScene(device);
2169 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2171 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2172 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2173 IDirect3DSurface8_Release(ds);
2175 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2176 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2177 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2178 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2180 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2181 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2183 /* Do the actual shadow mapping. */
2184 hr = IDirect3DDevice8_BeginScene(device);
2185 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2186 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2187 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2188 hr = IDirect3DDevice8_EndScene(device);
2189 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2191 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2192 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2193 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2194 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2195 IDirect3DTexture8_Release(texture);
2197 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2199 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2200 ok(color_match(color, expected_colors[j].color, 0),
2201 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2202 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2203 formats[i].name, color);
2206 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2207 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2210 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2211 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2212 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2213 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2215 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2216 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2217 IDirect3DSurface8_Release(original_ds);
2219 IDirect3DSurface8_Release(original_rt);
2220 IDirect3DSurface8_Release(rt);
2222 IDirect3D8_Release(d3d8);
2227 IDirect3DDevice8 *device_ptr;
2232 d3d8_handle = LoadLibraryA("d3d8.dll");
2235 win_skip("Could not load d3d8.dll\n");
2239 device_ptr = init_d3d8();
2242 win_skip("Could not initialize direct3d\n");
2246 IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
2248 /* Check for the reliability of the returned data */
2249 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2252 skip("Clear failed, can't assure correctness of the test results\n");
2256 color = getPixelColor(device_ptr, 1, 1);
2257 if(color !=0x00ff0000)
2259 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
2262 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
2264 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
2267 skip("Clear failed, can't assure correctness of the test results\n");
2271 color = getPixelColor(device_ptr, 639, 479);
2272 if(color != 0x0000ddee)
2274 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
2277 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
2279 /* Now run the real test */
2280 depth_clamp_test(device_ptr);
2281 lighting_test(device_ptr);
2282 clear_test(device_ptr);
2283 fog_test(device_ptr);
2284 present_test(device_ptr);
2285 offscreen_test(device_ptr);
2286 alpha_test(device_ptr);
2288 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
2290 test_rcp_rsq(device_ptr);
2294 skip("No vs.1.1 support\n");
2297 p8_texture_test(device_ptr);
2298 texop_test(device_ptr);
2299 depth_buffer_test(device_ptr);
2300 depth_buffer2_test(device_ptr);
2301 intz_test(device_ptr);
2302 shadow_test(device_ptr);
2306 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
2309 IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
2310 DestroyWindow(creation_parameters.hFocusWindow);
2311 refcount = IDirect3DDevice8_Release(device_ptr);
2312 ok(!refcount, "Device has %u references left\n", refcount);