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;
38 static HWND create_window(void)
42 wc.lpfnWndProc = DefWindowProc;
43 wc.lpszClassName = "d3d8_test_wc";
46 ret = CreateWindow("d3d8_test_wc", "d3d8_test",
47 WS_POPUP | WS_SYSMENU , 20, 20, 640, 480, 0, 0, 0, 0);
48 ShowWindow(ret, SW_SHOW);
52 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
67 IDirect3DTexture8 *tex = NULL;
68 IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
70 D3DLOCKED_RECT lockedRect;
71 RECT rectToLock = {x, y, x+1, y+1};
73 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
74 if(FAILED(hr) || !tex ) /* This is not a test */
76 trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr);
79 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &surf);
80 if(FAILED(hr) || !tex ) /* This is not a test */
82 trace("Can't get surface from texture, hr=%#08x\n", hr);
87 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
90 trace("Can't get the render target, hr=%#08x\n", hr);
94 hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
97 trace("Can't read the render target, hr=%#08x\n", hr);
102 hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
105 trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
109 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
110 * really important for these tests
112 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
113 hr = IDirect3DSurface8_UnlockRect(surf);
116 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
120 if(backbuf) IDirect3DSurface8_Release(backbuf);
121 if(surf) IDirect3DSurface8_Release(surf);
122 if(tex) IDirect3DTexture8_Release(tex);
126 static IDirect3DDevice8 *init_d3d8(void)
128 IDirect3D8 * (__stdcall * d3d8_create)(UINT SDKVersion) = 0;
129 IDirect3D8 *d3d8_ptr = 0;
130 IDirect3DDevice8 *device_ptr = 0;
131 D3DPRESENT_PARAMETERS present_parameters;
134 d3d8_create = (void *)GetProcAddress(d3d8_handle, "Direct3DCreate8");
135 ok(d3d8_create != NULL, "Failed to get address of Direct3DCreate8\n");
136 if (!d3d8_create) return NULL;
138 d3d8_ptr = d3d8_create(D3D_SDK_VERSION);
141 skip("could not create D3D8\n");
145 ZeroMemory(&present_parameters, sizeof(present_parameters));
146 present_parameters.Windowed = TRUE;
147 present_parameters.hDeviceWindow = create_window();
148 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
149 present_parameters.BackBufferWidth = 640;
150 present_parameters.BackBufferHeight = 480;
151 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
152 present_parameters.EnableAutoDepthStencil = TRUE;
153 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
155 hr = IDirect3D8_CreateDevice(d3d8_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
156 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
157 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL || broken(hr == D3DERR_NOTAVAILABLE), "IDirect3D_CreateDevice returned: %#08x\n", hr);
181 static void lighting_test(IDirect3DDevice8 *device)
184 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
185 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
188 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
189 0.0f, 1.0f, 0.0f, 0.0f,
190 0.0f, 0.0f, 1.0f, 0.0f,
191 0.0f, 0.0f, 0.0f, 1.0f };
193 struct vertex unlitquad[] =
195 {-1.0f, -1.0f, 0.1f, 0xffff0000},
196 {-1.0f, 0.0f, 0.1f, 0xffff0000},
197 { 0.0f, 0.0f, 0.1f, 0xffff0000},
198 { 0.0f, -1.0f, 0.1f, 0xffff0000},
200 struct vertex litquad[] =
202 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
203 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
204 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
205 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
207 struct nvertex unlitnquad[] =
209 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
210 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
211 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
212 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
214 struct nvertex litnquad[] =
216 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
217 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
218 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
219 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
221 WORD Indices[] = {0, 1, 2, 2, 3, 0};
223 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
224 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
226 /* Setup some states that may cause issues */
227 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
228 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
229 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
230 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
231 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
232 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
233 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
234 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
235 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
236 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
237 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
238 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
239 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
240 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
241 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
242 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
243 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
244 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
245 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
246 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
247 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
248 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
250 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
251 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
253 hr = IDirect3DDevice8_BeginScene(device);
254 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr);
257 /* No lights are defined... That means, lit vertices should be entirely black */
258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
259 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
260 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
261 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
262 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
265 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
266 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
267 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
268 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
270 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
271 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed with %#08x\n", hr);
273 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
274 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
275 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
276 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
277 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
279 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
280 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
281 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
282 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
283 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
285 hr = IDirect3DDevice8_EndScene(device);
286 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %#08x\n", hr);
289 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
290 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
291 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
292 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
293 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
294 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
295 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
296 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
298 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
300 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
304 static void clear_test(IDirect3DDevice8 *device)
306 /* Tests the correctness of clearing parameters */
312 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
313 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
315 /* Positive x, negative y */
321 /* Positive x, positive y */
326 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
327 * is ignored, the positive is still cleared afterwards
329 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
330 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
332 /* negative x, negative y */
333 rect_negneg.x1 = 640;
334 rect_negneg.y1 = 240;
335 rect_negneg.x2 = 320;
337 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
338 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
340 color = getPixelColor(device, 160, 360); /* lower left quad */
341 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
342 color = getPixelColor(device, 160, 120); /* upper left quad */
343 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
344 color = getPixelColor(device, 480, 360); /* lower right quad */
345 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
346 color = getPixelColor(device, 480, 120); /* upper right quad */
347 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
349 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
364 static void fog_test(IDirect3DDevice8 *device)
368 float start = 0.0, end = 1.0;
370 /* Gets full z based fog with linear fog, no fog with specular color */
371 struct sVertex untransformed_1[] = {
372 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
373 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
374 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
375 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
377 /* Ok, I am too lazy to deal with transform matrices */
378 struct sVertex untransformed_2[] = {
379 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
380 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
381 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
382 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
384 /* Untransformed ones. Give them a different diffuse color to make the test look
385 * nicer. It also makes making sure that they are drawn correctly easier.
387 struct sVertexT transformed_1[] = {
388 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
389 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
390 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
391 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
393 struct sVertexT transformed_2[] = {
394 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
395 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
396 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
397 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
399 WORD Indices[] = {0, 1, 2, 2, 3, 0};
402 float ident_mat[16] =
404 1.0f, 0.0f, 0.0f, 0.0f,
405 0.0f, 1.0f, 0.0f, 0.0f,
406 0.0f, 0.0f, 1.0f, 0.0f,
407 0.0f, 0.0f, 0.0f, 1.0f
409 float world_mat1[16] =
411 1.0f, 0.0f, 0.0f, 0.0f,
412 0.0f, 1.0f, 0.0f, 0.0f,
413 0.0f, 0.0f, 1.0f, 0.0f,
414 0.0f, 0.0f, -0.5f, 1.0f
416 float world_mat2[16] =
418 1.0f, 0.0f, 0.0f, 0.0f,
419 0.0f, 1.0f, 0.0f, 0.0f,
420 0.0f, 0.0f, 1.0f, 0.0f,
421 0.0f, 0.0f, 1.0f, 1.0f
425 1.0f, 0.0f, 0.0f, 0.0f,
426 0.0f, 1.0f, 0.0f, 0.0f,
427 0.0f, 0.0f, 1.0f, 0.0f,
428 0.0f, 0.0f, -1.0f, 1.0f
431 struct sVertex far_quad1[] =
433 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
434 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
435 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
436 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
438 struct sVertex far_quad2[] =
440 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
441 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
442 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
443 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
446 memset(&caps, 0, sizeof(caps));
447 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
448 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
450 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
451 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
453 /* Setup initial states: No lighting, fog on, fog color */
454 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
456 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
457 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
458 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
459 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
461 /* First test: Both table fog and vertex fog off */
462 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
463 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
465 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
467 /* Start = 0, end = 1. Should be default, but set them */
468 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
469 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
470 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
471 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
473 if(IDirect3DDevice8_BeginScene(device) == D3D_OK)
475 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
476 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
477 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
478 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
479 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
480 sizeof(untransformed_1[0]));
481 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
483 /* That makes it use the Z value */
484 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
485 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
486 /* Untransformed, vertex fog != none (or table fog != none):
487 * Use the Z value as input into the equation
489 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
490 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
491 sizeof(untransformed_2[0]));
492 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
494 /* transformed verts */
495 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
496 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
497 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
498 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
499 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
500 sizeof(transformed_1[0]));
501 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
503 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
504 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
505 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
508 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
509 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
510 sizeof(transformed_2[0]));
511 ok(SUCCEEDED(hr), "IDirect3DDevice8_DrawIndexedPrimitiveUP returned %#x.\n", hr);
513 hr = IDirect3DDevice8_EndScene(device);
514 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
518 ok(FALSE, "BeginScene failed\n");
521 color = getPixelColor(device, 160, 360);
522 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
523 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
524 color = getPixelColor(device, 160, 120);
525 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
526 "Untransformed vertex with linear vertex fog has color %08x\n", color);
527 color = getPixelColor(device, 480, 120);
528 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
529 "Transformed vertex with linear vertex fog has color %08x\n", color);
530 color = getPixelColor(device, 480, 360);
531 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
532 "Transformed vertex with linear table fog has color %08x\n", color);
534 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
536 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
538 /* A simple fog + non-identity world matrix test */
539 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat1);
540 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
542 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
543 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
544 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
545 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
547 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
548 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
550 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
552 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
553 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
555 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
556 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
557 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
559 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
560 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
561 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
563 hr = IDirect3DDevice8_EndScene(device);
564 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
568 ok(FALSE, "BeginScene failed\n");
571 color = getPixelColor(device, 160, 360);
572 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
573 color = getPixelColor(device, 160, 120);
574 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
575 "Fogged out quad has color %08x\n", color);
577 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
579 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
580 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat2);
581 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
582 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) proj_mat);
583 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
585 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
586 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
588 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
590 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
591 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
593 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
594 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
595 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
597 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
598 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
599 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
601 hr = IDirect3DDevice8_EndScene(device);
602 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
606 ok(FALSE, "BeginScene failed\n");
609 color = getPixelColor(device, 160, 360);
610 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
611 color = getPixelColor(device, 160, 120);
612 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
613 "Fogged out quad has color %08x\n", color);
615 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
617 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) ident_mat);
618 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
619 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) ident_mat);
620 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
624 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
627 /* Turn off the fog master switch to avoid confusing other tests */
628 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
629 ok(hr == D3D_OK, "Turning off fog calculations returned %#08x\n", hr);
632 /* This tests fog in combination with shaders.
633 * What's tested: linear fog (vertex and table) with pixel shader
634 * linear table fog with non foggy vertex shader
635 * vertex fog with foggy vertex shader, non-linear
636 * fog with shader, non-linear fog with foggy shader,
637 * linear table fog with foggy shader */
638 static void fog_with_shader_test(IDirect3DDevice8 *device)
649 /* Basic vertex shader without fog computation ("non foggy") */
650 static const DWORD vertex_shader_code1[] =
652 0xfffe0100, /* vs.1.0 */
653 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
654 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
657 /* Basic vertex shader with reversed fog computation ("foggy") */
658 static const DWORD vertex_shader_code2[] =
660 0xfffe0100, /* vs.1.0 */
661 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
662 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
663 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
664 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
667 /* Basic pixel shader */
668 static const DWORD pixel_shader_code[] =
670 0xffff0101, /* ps_1_1 */
671 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
674 static struct vertex quad[] =
676 {-1.0f, -1.0f, 0.0f, 0xffff0000},
677 {-1.0f, 1.0f, 0.0f, 0xffff0000},
678 { 1.0f, -1.0f, 0.0f, 0xffff0000},
679 { 1.0f, 1.0f, 0.0f, 0xffff0000},
681 static const DWORD decl[] =
684 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
685 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
688 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
689 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
690 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
691 DWORD pixel_shader[2] = {0, 0};
693 /* This reference data was collected on a nVidia GeForce 7600GS
694 * driver version 84.19 DirectX version 9.0c on Windows XP */
695 static const struct test_data_t
701 unsigned int color[11];
705 /* Only pixel shader */
706 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
707 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
708 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
709 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
710 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
711 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
712 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
713 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
714 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
715 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
716 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
717 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
718 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
719 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
720 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
723 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
724 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
725 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
726 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
727 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
728 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
729 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
730 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
731 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
733 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
734 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
735 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
736 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
737 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
738 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
740 /* Vertex shader and pixel shader */
741 /* The next 4 tests would read the fog coord output, but it isn't available.
742 * The result is a fully fogged quad, no matter what the Z coord is. */
743 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
744 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
745 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
746 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
747 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
748 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
749 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
750 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
751 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
752 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
753 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
754 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
756 /* These use the Z coordinate with linear table fog */
757 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
758 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
759 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
760 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
761 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
762 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
763 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
764 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
765 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
766 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
767 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
768 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
770 /* Non-linear table fog without fog coord */
771 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
772 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
773 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
774 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
775 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
776 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
778 /* These tests fail on older Nvidia drivers */
779 /* Foggy vertex shader */
780 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
781 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
782 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
783 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
784 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
785 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
786 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
787 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
788 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
789 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
790 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
791 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
793 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
794 * all using the fixed fog-coord linear fog */
795 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
796 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
797 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
798 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
799 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
800 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
801 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
802 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
803 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
804 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
805 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
806 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
808 /* These use table fog. Here the shader-provided fog coordinate is
809 * ignored and the z coordinate used instead */
810 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
811 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
812 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
813 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
814 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
815 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
816 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
817 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
818 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
821 /* NOTE: changing these values will not affect the tests with foggy vertex shader,
822 * as the values are hardcoded in the shader constant */
826 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
827 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
828 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
829 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
830 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
831 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
833 /* Set shader constant value */
834 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
835 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
837 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
839 /* Setup initial states: No lighting, fog on, fog color */
840 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
841 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
842 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
843 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
844 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
845 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
847 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
848 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
849 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
850 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
852 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
853 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
854 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
855 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
856 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
858 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
860 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
861 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
862 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
863 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
864 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
865 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
866 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
867 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
869 for(j = 0; j < 11; ++j)
871 /* Don't use the whole zrange to prevent rounding errors */
872 quad[0].z = 0.001f + j / 10.02f;
873 quad[1].z = 0.001f + j / 10.02f;
874 quad[2].z = 0.001f + j / 10.02f;
875 quad[3].z = 0.001f + j / 10.02f;
877 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0f, 0);
878 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
880 hr = IDirect3DDevice8_BeginScene(device);
881 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
883 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
884 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
886 hr = IDirect3DDevice8_EndScene(device);
887 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
889 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
890 color = getPixelColor(device, 128, 240);
891 ok(color_match(color, test_data[i].color[j], 13),
892 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
893 test_data[i].vshader, test_data[i].pshader,
894 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
896 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
901 hr = IDirect3DDevice8_SetVertexShader(device, 0);
902 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
903 hr = IDirect3DDevice8_SetPixelShader(device, 0);
904 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
905 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
906 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
908 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
909 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
910 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
913 static void present_test(IDirect3DDevice8 *device)
915 struct vertex quad[] =
917 {-1.0f, -1.0f, 0.9f, 0xffff0000},
918 {-1.0f, 1.0f, 0.9f, 0xffff0000},
919 { 1.0f, -1.0f, 0.1f, 0xffff0000},
920 { 1.0f, 1.0f, 0.1f, 0xffff0000},
925 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
926 * then call Present. Then clear the color buffer to make sure it has some defined content
927 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
928 * by the depth value.
930 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
931 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
932 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
933 ok(SUCCEEDED(hr), "IDirect3DDevice8_Present returned %#x.\n", hr);
934 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4f, 0);
935 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear returned %#x.\n", hr);
937 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
938 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
939 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
940 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
941 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
942 ok(hr == D3D_OK, "IDirect3DDevice8_SetFVF returned %08x\n", hr);
944 hr = IDirect3DDevice8_BeginScene(device);
945 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %08x\n", hr);
948 /* No lights are defined... That means, lit vertices should be entirely black */
949 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
950 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %08x\n", hr);
952 hr = IDirect3DDevice8_EndScene(device);
953 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %08x\n", hr);
956 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
957 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
959 color = getPixelColor(device, 512, 240);
960 ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
961 color = getPixelColor(device, 64, 240);
962 ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
964 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
965 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
968 static void test_rcp_rsq(IDirect3DDevice8 *device)
973 float constant[4] = {1.0, 1.0, 1.0, 2.0};
975 static const float quad[][3] = {
976 {-1.0f, -1.0f, 0.0f},
978 { 1.0f, -1.0f, 0.0f},
982 const DWORD rcp_test[] = {
983 0xfffe0101, /* vs.1.1 */
985 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
986 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
987 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
988 0x00303030, /* enough to make windows happy */
990 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
991 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
995 const DWORD rsq_test[] = {
996 0xfffe0101, /* vs.1.1 */
998 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
999 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
1000 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1001 0x00303030, /* enough to make windows happy */
1003 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1004 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
1005 0x0000ffff /* END */
1011 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* D3DVSDE_POSITION, Register v0 */
1015 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
1016 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1018 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
1019 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
1021 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1022 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1023 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
1025 hr = IDirect3DDevice8_BeginScene(device);
1026 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
1029 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1030 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
1031 hr = IDirect3DDevice8_EndScene(device);
1032 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
1035 color = getPixelColor(device, 320, 240);
1036 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), 4),
1037 "RCP test returned color 0x%08x, expected 0x00808080.\n", color);
1039 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1040 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
1042 IDirect3DDevice8_SetVertexShader(device, 0);
1043 IDirect3DDevice8_DeleteVertexShader(device, shader);
1045 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff996633, 0.0f, 0);
1046 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1048 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
1049 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
1051 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1052 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1053 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
1055 hr = IDirect3DDevice8_BeginScene(device);
1056 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
1059 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1060 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
1061 hr = IDirect3DDevice8_EndScene(device);
1062 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
1065 color = getPixelColor(device, 320, 240);
1066 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), 4),
1067 "RSQ test returned color 0x%08x, expected 0x00b4b4b4.\n", color);
1069 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1070 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
1072 IDirect3DDevice8_SetVertexShader(device, 0);
1073 IDirect3DDevice8_DeleteVertexShader(device, shader);
1076 static void offscreen_test(IDirect3DDevice8 *device)
1079 IDirect3DTexture8 *offscreenTexture = NULL;
1080 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
1083 static const float quad[][5] = {
1084 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1085 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1086 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1087 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1090 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
1091 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
1093 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1094 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
1096 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
1097 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1098 if(!offscreenTexture) {
1099 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1100 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
1101 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1102 if(!offscreenTexture) {
1103 skip("Cannot create an offscreen render target\n");
1108 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1109 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
1114 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1115 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
1120 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1121 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1123 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1124 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1125 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1126 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1127 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
1128 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
1129 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
1130 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
1131 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1132 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
1134 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
1135 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
1136 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
1137 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1138 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
1140 /* Draw without textures - Should result in a white quad */
1141 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1142 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1144 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1145 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
1146 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1147 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1149 /* This time with the texture */
1150 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1151 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1153 IDirect3DDevice8_EndScene(device);
1156 /* Center quad - should be white */
1157 color = getPixelColor(device, 320, 240);
1158 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1159 /* Some quad in the cleared part of the texture */
1160 color = getPixelColor(device, 170, 240);
1161 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1162 /* Part of the originally cleared back buffer */
1163 color = getPixelColor(device, 10, 10);
1164 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1166 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1167 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1168 * the offscreen rendering mode this test would succeed or fail
1170 color = getPixelColor(device, 10, 470);
1171 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1174 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1177 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1178 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetTexture returned %#x.\n", hr);
1180 /* restore things */
1182 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1183 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetRenderTarget returned %#x.\n", hr);
1184 IDirect3DSurface8_Release(backbuffer);
1186 if(offscreenTexture) {
1187 IDirect3DTexture8_Release(offscreenTexture);
1190 IDirect3DSurface8_Release(offscreen);
1193 IDirect3DSurface8_Release(depthstencil);
1197 static void alpha_test(IDirect3DDevice8 *device)
1200 IDirect3DTexture8 *offscreenTexture;
1201 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
1204 struct vertex quad1[] =
1206 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
1207 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
1208 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
1209 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
1211 struct vertex quad2[] =
1213 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
1214 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
1215 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
1216 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
1218 static const float composite_quad[][5] = {
1219 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
1220 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
1221 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
1222 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
1225 /* Clear the render target with alpha = 0.5 */
1226 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1227 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1229 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
1230 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1232 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
1233 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
1235 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1236 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
1240 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1241 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
1246 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1247 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1249 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1250 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1251 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1252 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1253 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
1254 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
1255 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
1256 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
1257 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1258 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
1260 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1261 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1262 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
1264 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
1265 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1266 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1268 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1269 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1270 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1272 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1273 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1275 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1276 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1277 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1279 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
1280 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
1281 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
1282 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
1283 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1284 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1285 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1287 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1288 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1289 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1290 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1291 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1292 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1294 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1295 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1296 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1297 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1298 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1299 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1301 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1302 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1304 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1305 * Disable alpha blending for the final composition
1307 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1308 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1309 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1310 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1312 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1313 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1314 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
1315 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1316 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1317 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1319 hr = IDirect3DDevice8_EndScene(device);
1320 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1323 color = getPixelColor(device, 160, 360);
1324 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1325 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
1327 color = getPixelColor(device, 160, 120);
1328 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
1329 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
1331 color = getPixelColor(device, 480, 360);
1332 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1333 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
1335 color = getPixelColor(device, 480, 120);
1336 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1337 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
1339 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1342 /* restore things */
1344 IDirect3DSurface8_Release(backbuffer);
1346 if(offscreenTexture) {
1347 IDirect3DTexture8_Release(offscreenTexture);
1350 IDirect3DSurface8_Release(offscreen);
1353 IDirect3DSurface8_Release(depthstencil);
1357 static void p8_texture_test(IDirect3DDevice8 *device)
1359 IDirect3D8 *d3d = NULL;
1361 IDirect3DTexture8 *texture = NULL, *texture2 = NULL;
1363 unsigned char *data;
1364 DWORD color, red, green, blue;
1365 PALETTEENTRY table[256];
1369 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
1370 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
1371 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
1372 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
1375 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
1376 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
1377 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
1378 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
1381 IDirect3DDevice8_GetDirect3D(device, &d3d);
1383 if(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1384 D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK) {
1385 skip("D3DFMT_P8 textures not supported\n");
1389 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1390 D3DPOOL_MANAGED, &texture2);
1391 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1393 skip("Failed to create D3DFMT_P8 texture\n");
1397 memset(&lr, 0, sizeof(lr));
1398 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
1399 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1403 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
1404 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1406 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1407 D3DPOOL_MANAGED, &texture);
1408 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1410 skip("Failed to create D3DFMT_P8 texture\n");
1414 memset(&lr, 0, sizeof(lr));
1415 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
1416 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1420 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1421 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1423 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1424 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1426 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1427 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1429 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
1430 alpha of every entry is set to 1.0, which MS says is required when there's no
1431 D3DPTEXTURECAPS_ALPHAPALETTE capability */
1432 for (i = 0; i < 256; i++) {
1433 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1434 table[i].peFlags = 0xff;
1436 table[1].peRed = 0xff;
1437 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1438 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1441 table[1].peBlue = 0xff;
1442 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1443 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1445 hr = IDirect3DDevice8_BeginScene(device);
1446 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1448 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1449 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1450 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1451 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1453 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1454 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1456 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1457 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1459 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1460 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1461 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1462 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1464 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
1465 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1466 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1467 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1469 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1470 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1471 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1472 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1474 hr = IDirect3DDevice8_EndScene(device);
1475 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1478 color = getPixelColor(device, 32, 32);
1479 red = (color & 0x00ff0000) >> 16;
1480 green = (color & 0x0000ff00) >> 8;
1481 blue = (color & 0x000000ff) >> 0;
1482 ok(red == 0xff && blue == 0 && green == 0,
1483 "got color %08x, expected 0x00ff0000\n", color);
1485 color = getPixelColor(device, 32, 320);
1486 red = (color & 0x00ff0000) >> 16;
1487 green = (color & 0x0000ff00) >> 8;
1488 blue = (color & 0x000000ff) >> 0;
1489 ok(red == 0 && blue == 0xff && green == 0,
1490 "got color %08x, expected 0x000000ff\n", color);
1492 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1493 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1495 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1496 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1498 hr = IDirect3DDevice8_BeginScene(device);
1499 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1501 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1502 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1504 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1505 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1507 hr = IDirect3DDevice8_EndScene(device);
1508 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1512 color = getPixelColor(device, 32, 32);
1513 red = (color & 0x00ff0000) >> 16;
1514 green = (color & 0x0000ff00) >> 8;
1515 blue = (color & 0x000000ff) >> 0;
1516 ok(red == 0 && blue == 0xff && green == 0,
1517 "got color %08x, expected 0x000000ff\n", color);
1519 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1520 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1522 /* Test palettes with alpha */
1523 IDirect3DDevice8_GetDeviceCaps(device, &caps);
1524 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
1525 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
1527 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1528 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1530 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1531 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1533 for (i = 0; i < 256; i++) {
1534 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1535 table[i].peFlags = 0xff;
1537 table[1].peRed = 0xff;
1538 table[1].peFlags = 0x80;
1539 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1540 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1543 table[1].peBlue = 0xff;
1544 table[1].peFlags = 0x80;
1545 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1546 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1548 hr = IDirect3DDevice8_BeginScene(device);
1549 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1551 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1552 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1553 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1554 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1556 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1557 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1559 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1560 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1562 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1563 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1565 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1566 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1568 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1569 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1571 hr = IDirect3DDevice8_EndScene(device);
1572 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1575 color = getPixelColor(device, 32, 32);
1576 red = (color & 0x00ff0000) >> 16;
1577 green = (color & 0x0000ff00) >> 8;
1578 blue = (color & 0x000000ff) >> 0;
1579 ok(red >= 0x7e && red <= 0x81 && blue == 0 && green == 0,
1580 "got color %08x, expected 0x00800000 or near\n", color);
1582 color = getPixelColor(device, 32, 320);
1583 red = (color & 0x00ff0000) >> 16;
1584 green = (color & 0x0000ff00) >> 8;
1585 blue = (color & 0x000000ff) >> 0;
1586 ok(red == 0 && blue >= 0x7e && blue <= 0x81 && green == 0,
1587 "got color %08x, expected 0x00000080 or near\n", color);
1589 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1590 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1593 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1594 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1595 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1596 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1599 if(texture) IDirect3DTexture8_Release(texture);
1600 if(texture2) IDirect3DTexture8_Release(texture2);
1601 IDirect3D8_Release(d3d);
1604 static void texop_test(IDirect3DDevice8 *device)
1606 IDirect3DTexture8 *texture = NULL;
1607 D3DLOCKED_RECT locked_rect;
1613 static const struct {
1618 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
1619 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
1620 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
1621 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
1624 static const struct {
1630 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1631 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
1632 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
1633 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
1634 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1635 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1637 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
1638 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1640 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1641 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1642 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1643 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
1644 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
1645 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1646 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1647 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
1648 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
1649 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1650 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
1651 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
1652 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
1653 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
1654 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
1657 memset(&caps, 0, sizeof(caps));
1658 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1659 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
1661 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
1662 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
1664 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
1665 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
1666 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
1667 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1668 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
1669 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1670 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1671 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1672 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1674 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
1675 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1676 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1677 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1678 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
1679 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1681 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
1682 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1684 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1685 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1686 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
1687 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1688 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
1689 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1691 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1692 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1694 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1696 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
1698 skip("tex operation %s not supported\n", test_data[i].name);
1702 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
1703 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
1705 hr = IDirect3DDevice8_BeginScene(device);
1706 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
1708 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1709 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
1711 hr = IDirect3DDevice8_EndScene(device);
1712 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
1714 color = getPixelColor(device, 320, 240);
1715 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
1716 test_data[i].name, color, test_data[i].result);
1718 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1719 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
1721 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1722 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1725 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1726 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1727 if (texture) IDirect3DTexture8_Release(texture);
1730 /* This test tests depth clamping / clipping behaviour:
1731 * - With software vertex processing, depth values are clamped to the
1732 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
1733 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
1734 * same as regular vertices here.
1735 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
1736 * Normal vertices are always clipped. Pretransformed vertices are
1737 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
1738 * - The viewport's MinZ/MaxZ is irrelevant for this.
1740 static void depth_clamp_test(IDirect3DDevice8 *device)
1742 const struct tvertex quad1[] =
1744 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1745 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1746 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1747 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1749 const struct tvertex quad2[] =
1751 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1752 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1753 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1754 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1756 const struct tvertex quad3[] =
1758 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1759 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1760 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1761 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1763 const struct tvertex quad4[] =
1765 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1766 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1767 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1768 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1770 const struct vertex quad5[] =
1772 { -0.5f, 0.5f, 10.0f, 0xff14f914},
1773 { 0.5f, 0.5f, 10.0f, 0xff14f914},
1774 { -0.5f, -0.5f, 10.0f, 0xff14f914},
1775 { 0.5f, -0.5f, 10.0f, 0xff14f914},
1777 const struct vertex quad6[] =
1779 { -1.0f, 0.5f, 10.0f, 0xfff91414},
1780 { 1.0f, 0.5f, 10.0f, 0xfff91414},
1781 { -1.0f, 0.25f, 10.0f, 0xfff91414},
1782 { 1.0f, 0.25f, 10.0f, 0xfff91414},
1797 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1798 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1800 hr = IDirect3DDevice8_SetViewport(device, &vp);
1801 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1803 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
1804 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1806 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1807 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1808 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1809 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1810 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1811 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1812 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1815 hr = IDirect3DDevice8_BeginScene(device);
1816 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1818 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1819 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
1821 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1823 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1824 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1826 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1827 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1829 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1831 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
1832 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1834 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1835 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1836 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1837 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1839 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
1840 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1842 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1843 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1845 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
1846 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1848 hr = IDirect3DDevice8_EndScene(device);
1849 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1851 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1853 color = getPixelColor(device, 75, 75);
1854 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1855 color = getPixelColor(device, 150, 150);
1856 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1857 color = getPixelColor(device, 320, 240);
1858 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1859 color = getPixelColor(device, 320, 330);
1860 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1861 color = getPixelColor(device, 320, 330);
1862 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1866 color = getPixelColor(device, 75, 75);
1867 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1868 color = getPixelColor(device, 150, 150);
1869 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1870 color = getPixelColor(device, 320, 240);
1871 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
1872 color = getPixelColor(device, 320, 330);
1873 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1874 color = getPixelColor(device, 320, 330);
1875 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1878 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1879 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1883 hr = IDirect3DDevice8_SetViewport(device, &vp);
1884 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1887 static void depth_buffer_test(IDirect3DDevice8 *device)
1889 static const struct vertex quad1[] =
1891 { -1.0, 1.0, 0.33f, 0xff00ff00},
1892 { 1.0, 1.0, 0.33f, 0xff00ff00},
1893 { -1.0, -1.0, 0.33f, 0xff00ff00},
1894 { 1.0, -1.0, 0.33f, 0xff00ff00},
1896 static const struct vertex quad2[] =
1898 { -1.0, 1.0, 0.50f, 0xffff00ff},
1899 { 1.0, 1.0, 0.50f, 0xffff00ff},
1900 { -1.0, -1.0, 0.50f, 0xffff00ff},
1901 { 1.0, -1.0, 0.50f, 0xffff00ff},
1903 static const struct vertex quad3[] =
1905 { -1.0, 1.0, 0.66f, 0xffff0000},
1906 { 1.0, 1.0, 0.66f, 0xffff0000},
1907 { -1.0, -1.0, 0.66f, 0xffff0000},
1908 { 1.0, -1.0, 0.66f, 0xffff0000},
1910 static const DWORD expected_colors[4][4] =
1912 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1913 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1914 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
1915 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
1918 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
1919 IDirect3DSurface8 *depth_stencil;
1932 hr = IDirect3DDevice8_SetViewport(device, &vp);
1933 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1935 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1936 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1937 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1938 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1939 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1940 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1941 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1942 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1943 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1944 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1946 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1947 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1948 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1949 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1950 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
1951 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1952 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1953 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1954 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1955 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1956 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1957 D3DMULTISAMPLE_NONE, FALSE, &rt3);
1958 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1960 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
1961 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1962 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
1963 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1965 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1966 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1967 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1968 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1970 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1971 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1972 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1973 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1975 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1976 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1977 hr = IDirect3DDevice8_BeginScene(device);
1978 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1979 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
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 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1985 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1987 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1988 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1990 hr = IDirect3DDevice8_BeginScene(device);
1991 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1992 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1994 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1995 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1996 hr = IDirect3DDevice8_EndScene(device);
1997 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1999 for (i = 0; i < 4; ++i)
2001 for (j = 0; j < 4; ++j)
2003 unsigned int x = 80 * ((2 * j) + 1);
2004 unsigned int y = 60 * ((2 * i) + 1);
2005 color = getPixelColor(device, x, y);
2006 ok(color_match(color, expected_colors[i][j], 0),
2007 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
2011 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2012 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2014 IDirect3DSurface8_Release(depth_stencil);
2015 IDirect3DSurface8_Release(backbuffer);
2016 IDirect3DSurface8_Release(rt3);
2017 IDirect3DSurface8_Release(rt2);
2018 IDirect3DSurface8_Release(rt1);
2021 /* Test that partial depth copies work the way they're supposed to. The clear
2022 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2023 * the following draw should only copy back the part that was modified. */
2024 static void depth_buffer2_test(IDirect3DDevice8 *device)
2026 static const struct vertex quad[] =
2028 { -1.0, 1.0, 0.66f, 0xffff0000},
2029 { 1.0, 1.0, 0.66f, 0xffff0000},
2030 { -1.0, -1.0, 0.66f, 0xffff0000},
2031 { 1.0, -1.0, 0.66f, 0xffff0000},
2034 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
2035 IDirect3DSurface8 *depth_stencil;
2048 hr = IDirect3DDevice8_SetViewport(device, &vp);
2049 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2051 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2052 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2053 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2054 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2055 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2056 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2057 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2058 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2059 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2060 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2062 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2063 D3DMULTISAMPLE_NONE, FALSE, &rt1);
2064 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2065 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
2066 D3DMULTISAMPLE_NONE, FALSE, &rt2);
2067 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2068 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
2069 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2070 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
2071 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2073 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
2074 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2075 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2076 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2078 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2079 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2080 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
2081 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2083 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
2084 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2085 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
2086 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2088 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2089 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2091 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2092 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2094 hr = IDirect3DDevice8_BeginScene(device);
2095 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2096 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2097 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2098 hr = IDirect3DDevice8_EndScene(device);
2099 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2101 for (i = 0; i < 4; ++i)
2103 for (j = 0; j < 4; ++j)
2105 unsigned int x = 80 * ((2 * j) + 1);
2106 unsigned int y = 60 * ((2 * i) + 1);
2107 color = getPixelColor(device, x, y);
2108 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
2109 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
2113 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2114 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2116 IDirect3DSurface8_Release(depth_stencil);
2117 IDirect3DSurface8_Release(backbuffer);
2118 IDirect3DSurface8_Release(rt2);
2119 IDirect3DSurface8_Release(rt1);
2122 static void intz_test(IDirect3DDevice8 *device)
2124 static const DWORD ps_code[] =
2126 0xffff0101, /* ps_1_1 */
2127 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2128 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2129 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2130 0x00000042, 0xb00f0000, /* tex t0 */
2131 0x00000042, 0xb00f0001, /* tex t1 */
2132 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2133 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2134 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2135 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2136 0x0000ffff, /* end */
2142 float s1, t1, p1, q1;
2146 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2147 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2148 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2149 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2153 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2154 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2155 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2156 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2160 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2161 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2162 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2163 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2172 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2173 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2174 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2175 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2176 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2177 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2178 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2179 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2182 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2183 IDirect3DTexture8 *texture;
2184 IDirect3DSurface8 *ds;
2191 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2192 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2193 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2195 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
2198 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2200 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2204 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2205 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2207 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2208 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2211 skip("No INTZ support, skipping INTZ test.\n");
2215 IDirect3D8_Release(d3d8);
2217 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2218 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2219 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2220 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2222 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2223 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2224 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2225 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2226 D3DMULTISAMPLE_NONE, FALSE, &rt);
2227 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2228 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2229 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2231 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2232 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2233 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2234 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2236 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2238 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2240 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2241 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2243 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2244 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2245 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2246 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2247 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2248 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2249 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2250 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2252 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2253 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2254 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2255 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2256 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2257 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2258 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2259 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2260 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2261 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2262 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2263 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2264 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2266 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2267 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2269 /* Render offscreen, using the INTZ texture as depth buffer */
2270 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2271 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2272 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2273 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2275 /* Setup the depth/stencil surface. */
2276 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2277 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2279 hr = IDirect3DDevice8_BeginScene(device);
2280 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2281 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2282 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2283 hr = IDirect3DDevice8_EndScene(device);
2284 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2286 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2287 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2288 IDirect3DSurface8_Release(ds);
2289 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2290 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2291 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2292 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2293 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2294 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2296 /* Read the depth values back. */
2297 hr = IDirect3DDevice8_BeginScene(device);
2298 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2299 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2301 hr = IDirect3DDevice8_EndScene(device);
2302 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2304 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2306 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2307 ok(color_match(color, expected_colors[i].color, 1),
2308 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2309 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2312 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2313 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2315 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2316 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2317 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2318 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2319 IDirect3DTexture8_Release(texture);
2321 /* Render onscreen while using the INTZ texture as depth buffer */
2322 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2323 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2324 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2325 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2326 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2327 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2328 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2329 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2330 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2332 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2333 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2335 hr = IDirect3DDevice8_BeginScene(device);
2336 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2337 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2338 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2339 hr = IDirect3DDevice8_EndScene(device);
2340 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2342 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2343 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2344 IDirect3DSurface8_Release(ds);
2345 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2346 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2347 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2348 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2349 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2350 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2352 /* Read the depth values back. */
2353 hr = IDirect3DDevice8_BeginScene(device);
2354 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2355 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2357 hr = IDirect3DDevice8_EndScene(device);
2358 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2360 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2362 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2363 ok(color_match(color, expected_colors[i].color, 1),
2364 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2365 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2368 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2369 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2371 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2372 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2373 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2374 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2375 IDirect3DTexture8_Release(texture);
2377 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
2378 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2379 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2380 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2381 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2382 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2383 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2384 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2385 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2386 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2388 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2389 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2391 hr = IDirect3DDevice8_BeginScene(device);
2392 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2393 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
2394 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2395 hr = IDirect3DDevice8_EndScene(device);
2396 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2398 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2399 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2401 hr = IDirect3DDevice8_BeginScene(device);
2402 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2403 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
2404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2405 hr = IDirect3DDevice8_EndScene(device);
2406 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2408 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2409 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2410 IDirect3DSurface8_Release(ds);
2411 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2412 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2413 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2414 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2415 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2416 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2418 /* Read the depth values back. */
2419 hr = IDirect3DDevice8_BeginScene(device);
2420 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2421 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2422 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2423 hr = IDirect3DDevice8_EndScene(device);
2424 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2426 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2428 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2429 ok(color_match(color, expected_colors[i].color, 1),
2430 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2431 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2434 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2435 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2437 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2438 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2439 IDirect3DSurface8_Release(original_ds);
2440 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2441 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2442 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2443 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2444 IDirect3DTexture8_Release(texture);
2445 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2446 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2447 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2448 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2450 IDirect3DSurface8_Release(original_rt);
2451 IDirect3DSurface8_Release(rt);
2454 static void shadow_test(IDirect3DDevice8 *device)
2456 static const DWORD ps_code[] =
2458 0xffff0101, /* ps_1_1 */
2459 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2460 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2461 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2462 0x00000042, 0xb00f0000, /* tex t0 */
2463 0x00000042, 0xb00f0001, /* tex t1 */
2464 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2465 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2466 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2467 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2468 0x0000ffff, /* end */
2477 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
2478 {D3DFMT_D32, "D3DFMT_D32"},
2479 {D3DFMT_D15S1, "D3DFMT_D15S1"},
2480 {D3DFMT_D24S8, "D3DFMT_D24S8"},
2481 {D3DFMT_D24X8, "D3DFMT_D24X8"},
2482 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
2483 {D3DFMT_D16, "D3DFMT_D16"},
2489 float s1, t1, p1, q1;
2493 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2494 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2495 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2496 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2505 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2506 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2507 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2508 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2509 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2510 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2511 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2512 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2515 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2522 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2523 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2524 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2526 skip("No pixel shader 1.1 support, skipping shadow test.\n");
2530 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2531 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2532 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2533 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2534 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2535 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2537 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2538 D3DMULTISAMPLE_NONE, FALSE, &rt);
2539 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2540 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2541 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2543 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2544 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2545 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2546 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2547 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2548 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2550 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2552 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2553 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2555 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2556 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2557 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2558 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2559 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2560 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2561 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2562 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2564 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2565 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2566 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2567 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2568 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2569 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2570 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2571 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2572 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2573 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2574 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2575 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2576 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2578 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2580 D3DFORMAT format = formats[i].format;
2581 IDirect3DTexture8 *texture;
2582 IDirect3DSurface8 *ds;
2585 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2586 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2587 if (FAILED(hr)) continue;
2589 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2590 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2591 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2593 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2594 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2596 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2597 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2599 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2600 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2602 /* Setup the depth/stencil surface. */
2603 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2604 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2606 hr = IDirect3DDevice8_BeginScene(device);
2607 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2608 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2609 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2610 hr = IDirect3DDevice8_EndScene(device);
2611 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2613 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2614 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2615 IDirect3DSurface8_Release(ds);
2617 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2618 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2619 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2620 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2622 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2623 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2625 /* Do the actual shadow mapping. */
2626 hr = IDirect3DDevice8_BeginScene(device);
2627 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2628 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2629 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2630 hr = IDirect3DDevice8_EndScene(device);
2631 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2633 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2634 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2635 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2636 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2637 IDirect3DTexture8_Release(texture);
2639 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2641 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2642 ok(color_match(color, expected_colors[j].color, 0),
2643 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2644 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2645 formats[i].name, color);
2648 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2649 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2652 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2653 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2654 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2655 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2657 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2658 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2659 IDirect3DSurface8_Release(original_ds);
2661 IDirect3DSurface8_Release(original_rt);
2662 IDirect3DSurface8_Release(rt);
2664 IDirect3D8_Release(d3d8);
2667 static void multisample_copy_rects_test(IDirect3DDevice8 *device)
2669 IDirect3DSurface8 *original_ds, *original_rt, *ds, *ds_plain, *rt, *readback;
2670 RECT src_rect = {64, 64, 128, 128};
2671 POINT dst_point = {96, 96};
2672 D3DLOCKED_RECT locked_rect;
2677 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2678 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2679 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2680 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2681 IDirect3D8_Release(d3d8);
2684 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
2688 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
2689 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2690 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2691 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2692 D3DMULTISAMPLE_2_SAMPLES, &ds);
2693 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2694 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2695 D3DMULTISAMPLE_NONE, &ds_plain);
2696 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2697 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
2698 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
2700 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2701 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2702 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2703 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2705 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2706 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2708 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2709 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2711 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
2712 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2714 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
2715 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2717 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2718 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2720 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
2721 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2723 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
2724 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
2726 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
2727 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2729 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
2730 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
2732 hr = IDirect3DSurface8_UnlockRect(readback);
2733 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
2735 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2736 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
2738 IDirect3DSurface8_Release(original_ds);
2739 IDirect3DSurface8_Release(original_rt);
2740 IDirect3DSurface8_Release(readback);
2741 IDirect3DSurface8_Release(ds_plain);
2742 IDirect3DSurface8_Release(ds);
2743 IDirect3DSurface8_Release(rt);
2746 static void resz_test(IDirect3DDevice8 *device)
2748 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
2753 static const DWORD ps_code[] =
2755 0xffff0101, /* ps_1_1 */
2756 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2757 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2758 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2759 0x00000042, 0xb00f0000, /* tex t0 */
2760 0x00000042, 0xb00f0001, /* tex t1 */
2761 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2762 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2763 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2764 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2765 0x0000ffff, /* end */
2771 float s1, t1, p1, q1;
2775 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2776 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2777 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2778 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2787 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2788 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2789 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2790 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2791 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2792 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2793 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2794 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2796 IDirect3DTexture8 *texture;
2799 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2800 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2801 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2802 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2805 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
2808 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2809 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2812 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
2815 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2816 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2819 skip("No INTZ support, skipping RESZ test.\n");
2822 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2823 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
2826 skip("No RESZ support, skipping RESZ test.\n");
2829 IDirect3D8_Release(d3d8);
2831 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2832 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2833 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2835 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2839 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2840 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2841 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2842 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2844 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2845 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2846 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2847 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2848 D3DMULTISAMPLE_2_SAMPLES, &ds);
2850 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2851 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2852 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2853 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
2854 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2856 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
2857 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2858 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
2859 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2861 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2862 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2863 IDirect3DSurface8_Release(intz_ds);
2864 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2865 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2867 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2868 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2869 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2870 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2871 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2872 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2873 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2874 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2875 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2876 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2877 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2879 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2880 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2881 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2882 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2883 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2884 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2885 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2886 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2888 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2889 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2890 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2891 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2892 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2893 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2894 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2895 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2896 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2897 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2898 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2899 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2900 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2902 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
2903 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2904 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_BeginScene(device);
2907 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2908 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2909 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2911 /* The destination depth texture has to be bound to sampler 0 */
2912 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2913 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2915 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
2916 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2918 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2919 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2920 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2921 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2922 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2923 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2924 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2925 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2926 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2927 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2928 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2929 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2931 /* The actual multisampled depth buffer resolve happens here */
2932 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2933 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2934 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
2935 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
2937 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2938 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2939 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2940 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2941 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2942 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2944 /* Read the depth values back. */
2945 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2946 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2947 hr = IDirect3DDevice8_EndScene(device);
2948 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2950 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2952 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2953 ok(color_match(color, expected_colors[i].color, 1),
2954 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2955 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2958 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2959 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2961 /* Test edge cases - try with no texture at all */
2962 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2963 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2964 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2965 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2966 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2967 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2969 hr = IDirect3DDevice8_BeginScene(device);
2970 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2971 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2972 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2973 hr = IDirect3DDevice8_EndScene(device);
2974 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2977 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2979 /* With a non-multisampled depth buffer */
2980 IDirect3DSurface8_Release(ds);
2981 IDirect3DSurface8_Release(rt);
2982 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2983 D3DMULTISAMPLE_NONE, &ds);
2985 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2986 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2987 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2988 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2990 hr = IDirect3DDevice8_BeginScene(device);
2991 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2992 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2994 hr = IDirect3DDevice8_EndScene(device);
2995 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2997 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2998 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3000 hr = IDirect3DDevice8_BeginScene(device);
3001 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3002 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3003 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3005 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
3007 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3008 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3009 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3010 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
3011 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3013 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3014 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
3015 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3016 hr = IDirect3DDevice8_EndScene(device);
3017 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3019 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3020 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3022 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3023 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3024 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3025 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3027 /* Read the depth values back. */
3028 hr = IDirect3DDevice8_BeginScene(device);
3029 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3030 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3032 hr = IDirect3DDevice8_EndScene(device);
3033 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3035 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3037 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3038 ok(color_match(color, expected_colors[i].color, 1),
3039 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3040 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3043 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3044 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3046 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
3047 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3048 IDirect3DSurface8_Release(ds);
3049 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3050 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3051 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3052 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3053 IDirect3DTexture8_Release(texture);
3054 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3055 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3056 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3057 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3058 IDirect3DSurface8_Release(original_ds);
3059 IDirect3DSurface8_Release(original_rt);
3062 static void zenable_test(IDirect3DDevice8 *device)
3066 struct vec4 position;
3071 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
3072 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
3073 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
3074 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
3082 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3083 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
3084 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3085 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3087 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3088 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3089 hr = IDirect3DDevice8_BeginScene(device);
3090 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3091 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
3092 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3093 hr = IDirect3DDevice8_EndScene(device);
3094 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3096 for (i = 0; i < 4; ++i)
3098 for (j = 0; j < 4; ++j)
3100 x = 80 * ((2 * j) + 1);
3101 y = 60 * ((2 * i) + 1);
3102 color = getPixelColor(device, x, y);
3103 ok(color_match(color, 0x0000ff00, 1),
3104 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
3108 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3109 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3111 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3112 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3114 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
3115 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3117 static const DWORD vs_code[] =
3119 0xfffe0101, /* vs_1_1 */
3120 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3121 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
3124 static const DWORD ps_code[] =
3126 0xffff0101, /* ps_1_1 */
3127 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
3128 0x0000ffff /* end */
3130 static const struct vec3 quad[] =
3132 {-1.0f, -1.0f, -0.5f},
3133 {-1.0f, 1.0f, -0.5f},
3134 { 1.0f, -1.0f, 1.5f},
3135 { 1.0f, 1.0f, 1.5f},
3137 static const D3DCOLOR expected[] =
3139 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
3140 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
3141 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
3142 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
3144 static const DWORD decl[] =
3147 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
3152 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
3153 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3154 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3155 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
3156 hr = IDirect3DDevice8_SetVertexShader(device, vs);
3157 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3158 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3159 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3161 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3162 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3163 hr = IDirect3DDevice8_BeginScene(device);
3164 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3165 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3166 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3167 hr = IDirect3DDevice8_EndScene(device);
3168 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3170 for (i = 0; i < 4; ++i)
3172 for (j = 0; j < 4; ++j)
3174 x = 80 * ((2 * j) + 1);
3175 y = 60 * ((2 * i) + 1);
3176 color = getPixelColor(device, x, y);
3177 ok(color_match(color, expected[i * 4 + j], 1),
3178 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
3182 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3183 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3185 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3186 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3187 hr = IDirect3DDevice8_SetVertexShader(device, 0);
3188 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3189 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3190 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
3191 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
3192 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
3198 IDirect3DDevice8 *device_ptr;
3203 d3d8_handle = LoadLibraryA("d3d8.dll");
3206 win_skip("Could not load d3d8.dll\n");
3210 device_ptr = init_d3d8();
3213 win_skip("Could not initialize direct3d\n");
3217 IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
3219 /* Check for the reliability of the returned data */
3220 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3223 skip("Clear failed, can't assure correctness of the test results\n");
3227 color = getPixelColor(device_ptr, 1, 1);
3228 if(color !=0x00ff0000)
3230 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3233 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3235 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3238 skip("Clear failed, can't assure correctness of the test results\n");
3242 color = getPixelColor(device_ptr, 639, 479);
3243 if(color != 0x0000ddee)
3245 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3248 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3250 /* Now run the real test */
3251 depth_clamp_test(device_ptr);
3252 lighting_test(device_ptr);
3253 clear_test(device_ptr);
3254 fog_test(device_ptr);
3255 present_test(device_ptr);
3256 offscreen_test(device_ptr);
3257 alpha_test(device_ptr);
3259 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3261 test_rcp_rsq(device_ptr);
3262 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
3263 fog_with_shader_test(device_ptr);
3267 skip("No vs.1.1 support\n");
3270 p8_texture_test(device_ptr);
3271 texop_test(device_ptr);
3272 depth_buffer_test(device_ptr);
3273 depth_buffer2_test(device_ptr);
3274 intz_test(device_ptr);
3275 shadow_test(device_ptr);
3276 multisample_copy_rects_test(device_ptr);
3277 zenable_test(device_ptr);
3278 resz_test(device_ptr);
3282 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
3285 IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
3286 DestroyWindow(creation_parameters.hFocusWindow);
3287 refcount = IDirect3DDevice8_Release(device_ptr);
3288 ok(!refcount, "Device has %u references left\n", refcount);