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);
1986 IDirect3DSurface8_Release(depth_stencil);
1987 IDirect3DSurface8_Release(backbuffer);
1988 IDirect3DSurface8_Release(rt3);
1989 IDirect3DSurface8_Release(rt2);
1990 IDirect3DSurface8_Release(rt1);
1992 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1993 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1995 hr = IDirect3DDevice8_BeginScene(device);
1996 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1997 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1998 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1999 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
2000 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2001 hr = IDirect3DDevice8_EndScene(device);
2002 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2004 for (i = 0; i < 4; ++i)
2006 for (j = 0; j < 4; ++j)
2008 unsigned int x = 80 * ((2 * j) + 1);
2009 unsigned int y = 60 * ((2 * i) + 1);
2010 color = getPixelColor(device, x, y);
2011 ok(color_match(color, expected_colors[i][j], 0),
2012 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
2016 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2017 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2020 /* Test that partial depth copies work the way they're supposed to. The clear
2021 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2022 * the following draw should only copy back the part that was modified. */
2023 static void depth_buffer2_test(IDirect3DDevice8 *device)
2025 static const struct vertex quad[] =
2027 { -1.0, 1.0, 0.66f, 0xffff0000},
2028 { 1.0, 1.0, 0.66f, 0xffff0000},
2029 { -1.0, -1.0, 0.66f, 0xffff0000},
2030 { 1.0, -1.0, 0.66f, 0xffff0000},
2033 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
2034 IDirect3DSurface8 *depth_stencil;
2047 hr = IDirect3DDevice8_SetViewport(device, &vp);
2048 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2050 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2051 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2052 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2053 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2054 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2056 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2058 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2059 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2061 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2062 D3DMULTISAMPLE_NONE, FALSE, &rt1);
2063 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2064 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
2065 D3DMULTISAMPLE_NONE, FALSE, &rt2);
2066 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2067 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
2068 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2069 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
2070 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2072 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
2073 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2074 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2075 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2077 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2078 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2079 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
2080 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2082 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
2083 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2084 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
2085 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2087 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2088 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2089 IDirect3DSurface8_Release(depth_stencil);
2090 IDirect3DSurface8_Release(backbuffer);
2091 IDirect3DSurface8_Release(rt2);
2092 IDirect3DSurface8_Release(rt1);
2094 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2095 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2097 hr = IDirect3DDevice8_BeginScene(device);
2098 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2099 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2100 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2101 hr = IDirect3DDevice8_EndScene(device);
2102 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2104 for (i = 0; i < 4; ++i)
2106 for (j = 0; j < 4; ++j)
2108 unsigned int x = 80 * ((2 * j) + 1);
2109 unsigned int y = 60 * ((2 * i) + 1);
2110 color = getPixelColor(device, x, y);
2111 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
2112 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
2116 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2117 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2120 static void intz_test(IDirect3DDevice8 *device)
2122 static const DWORD ps_code[] =
2124 0xffff0101, /* ps_1_1 */
2125 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2126 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2127 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2128 0x00000042, 0xb00f0000, /* tex t0 */
2129 0x00000042, 0xb00f0001, /* tex t1 */
2130 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2131 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2132 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2133 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2134 0x0000ffff, /* end */
2140 float s1, t1, p1, q1;
2144 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2145 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2146 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2147 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2151 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2152 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2153 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2154 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2158 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2159 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2160 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2161 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2170 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2171 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2172 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2173 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2174 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2175 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2176 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2177 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2180 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2181 IDirect3DTexture8 *texture;
2182 IDirect3DSurface8 *ds;
2189 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2190 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2191 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2193 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
2196 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2198 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2202 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2203 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2205 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2206 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2209 skip("No INTZ support, skipping INTZ test.\n");
2213 IDirect3D8_Release(d3d8);
2215 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2216 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2217 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2218 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2220 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2221 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2222 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2223 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2224 D3DMULTISAMPLE_NONE, FALSE, &rt);
2225 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2226 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2227 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2229 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2230 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2231 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2232 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2233 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2234 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2236 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2238 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2241 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2242 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2243 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2244 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2245 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2246 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2247 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2248 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2250 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2251 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2252 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2253 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2254 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2255 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2256 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2257 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2258 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2259 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2260 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2261 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2262 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2264 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2265 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2267 /* Render offscreen, using the INTZ texture as depth buffer */
2268 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2269 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2270 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2271 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2273 /* Setup the depth/stencil surface. */
2274 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2275 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2277 hr = IDirect3DDevice8_BeginScene(device);
2278 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2279 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2280 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2281 hr = IDirect3DDevice8_EndScene(device);
2282 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2284 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2285 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2286 IDirect3DSurface8_Release(ds);
2287 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2288 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2289 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2290 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2291 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2292 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2294 /* Read the depth values back. */
2295 hr = IDirect3DDevice8_BeginScene(device);
2296 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2297 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2298 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2299 hr = IDirect3DDevice8_EndScene(device);
2300 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2302 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2304 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2305 ok(color_match(color, expected_colors[i].color, 1),
2306 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2307 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2310 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2311 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2313 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2314 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2315 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2316 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2317 IDirect3DTexture8_Release(texture);
2319 /* Render onscreen while using the INTZ texture as depth buffer */
2320 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2321 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2322 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2323 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2324 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2325 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2326 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2327 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2328 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2330 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2331 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2333 hr = IDirect3DDevice8_BeginScene(device);
2334 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2335 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2336 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2337 hr = IDirect3DDevice8_EndScene(device);
2338 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2340 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2341 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2342 IDirect3DSurface8_Release(ds);
2343 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2344 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2345 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2346 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2347 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2348 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2350 /* Read the depth values back. */
2351 hr = IDirect3DDevice8_BeginScene(device);
2352 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2353 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2354 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2355 hr = IDirect3DDevice8_EndScene(device);
2356 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2358 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2360 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2361 ok(color_match(color, expected_colors[i].color, 1),
2362 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2363 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2366 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2367 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2369 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2370 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2371 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2372 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2373 IDirect3DTexture8_Release(texture);
2375 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
2376 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2377 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2378 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2379 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2380 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2381 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2382 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2383 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2384 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2386 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2387 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2389 hr = IDirect3DDevice8_BeginScene(device);
2390 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2391 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
2392 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2393 hr = IDirect3DDevice8_EndScene(device);
2394 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2396 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2397 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2399 hr = IDirect3DDevice8_BeginScene(device);
2400 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2401 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
2402 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2403 hr = IDirect3DDevice8_EndScene(device);
2404 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2406 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2407 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2408 IDirect3DSurface8_Release(ds);
2409 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2410 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2411 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2412 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2413 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2414 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2416 /* Read the depth values back. */
2417 hr = IDirect3DDevice8_BeginScene(device);
2418 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2419 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2421 hr = IDirect3DDevice8_EndScene(device);
2422 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2424 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2426 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2427 ok(color_match(color, expected_colors[i].color, 1),
2428 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2429 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2432 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2433 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2435 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2436 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2437 IDirect3DSurface8_Release(original_ds);
2438 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2439 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2440 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2441 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2442 IDirect3DTexture8_Release(texture);
2443 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2444 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2445 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2446 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2448 IDirect3DSurface8_Release(original_rt);
2449 IDirect3DSurface8_Release(rt);
2452 static void shadow_test(IDirect3DDevice8 *device)
2454 static const DWORD ps_code[] =
2456 0xffff0101, /* ps_1_1 */
2457 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2458 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2459 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2460 0x00000042, 0xb00f0000, /* tex t0 */
2461 0x00000042, 0xb00f0001, /* tex t1 */
2462 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2463 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2464 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2465 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2466 0x0000ffff, /* end */
2475 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
2476 {D3DFMT_D32, "D3DFMT_D32"},
2477 {D3DFMT_D15S1, "D3DFMT_D15S1"},
2478 {D3DFMT_D24S8, "D3DFMT_D24S8"},
2479 {D3DFMT_D24X8, "D3DFMT_D24X8"},
2480 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
2481 {D3DFMT_D16, "D3DFMT_D16"},
2487 float s1, t1, p1, q1;
2491 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2492 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2493 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2494 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2503 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2504 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2505 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2506 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2507 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2508 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2509 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2510 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2513 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2520 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2521 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2522 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2524 skip("No pixel shader 1.1 support, skipping shadow test.\n");
2528 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2529 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2530 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2531 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2532 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2533 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2535 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2536 D3DMULTISAMPLE_NONE, FALSE, &rt);
2537 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2538 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2539 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2541 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2542 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2543 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2544 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2545 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2546 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2547 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2548 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2550 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2553 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2554 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2555 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2556 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2557 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2558 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2559 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2560 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2562 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2563 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2564 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2565 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2566 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2567 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2568 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2569 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2570 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2571 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2572 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2573 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2574 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2576 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2578 D3DFORMAT format = formats[i].format;
2579 IDirect3DTexture8 *texture;
2580 IDirect3DSurface8 *ds;
2583 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2584 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2585 if (FAILED(hr)) continue;
2587 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2588 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2589 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2591 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2592 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2594 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2595 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2597 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2598 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2600 /* Setup the depth/stencil surface. */
2601 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2602 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2604 hr = IDirect3DDevice8_BeginScene(device);
2605 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2606 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2608 hr = IDirect3DDevice8_EndScene(device);
2609 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2611 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2612 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2613 IDirect3DSurface8_Release(ds);
2615 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2616 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2617 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2618 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2620 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2621 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2623 /* Do the actual shadow mapping. */
2624 hr = IDirect3DDevice8_BeginScene(device);
2625 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2626 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2627 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2628 hr = IDirect3DDevice8_EndScene(device);
2629 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2631 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2632 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2633 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2634 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2635 IDirect3DTexture8_Release(texture);
2637 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2639 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2640 ok(color_match(color, expected_colors[j].color, 0),
2641 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2642 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2643 formats[i].name, color);
2646 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2647 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2650 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2651 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2652 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2653 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2655 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2656 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2657 IDirect3DSurface8_Release(original_ds);
2659 IDirect3DSurface8_Release(original_rt);
2660 IDirect3DSurface8_Release(rt);
2662 IDirect3D8_Release(d3d8);
2665 static void multisample_copy_rects_test(IDirect3DDevice8 *device)
2667 IDirect3DSurface8 *original_ds, *original_rt, *ds, *ds_plain, *rt, *readback;
2668 RECT src_rect = {64, 64, 128, 128};
2669 POINT dst_point = {96, 96};
2670 D3DLOCKED_RECT locked_rect;
2675 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2676 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2677 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2678 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2679 IDirect3D8_Release(d3d8);
2682 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
2686 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
2687 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2688 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2689 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2690 D3DMULTISAMPLE_2_SAMPLES, &ds);
2691 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2692 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2693 D3DMULTISAMPLE_NONE, &ds_plain);
2694 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2695 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
2696 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
2698 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2699 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2700 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2701 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2703 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2704 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2706 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2707 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2709 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
2710 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2712 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
2713 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2715 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2716 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2718 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
2719 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2721 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
2722 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
2724 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
2725 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2727 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
2728 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
2730 hr = IDirect3DSurface8_UnlockRect(readback);
2731 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
2733 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2734 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
2736 IDirect3DSurface8_Release(original_ds);
2737 IDirect3DSurface8_Release(original_rt);
2738 IDirect3DSurface8_Release(readback);
2739 IDirect3DSurface8_Release(ds_plain);
2740 IDirect3DSurface8_Release(ds);
2741 IDirect3DSurface8_Release(rt);
2744 static void resz_test(IDirect3DDevice8 *device)
2746 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
2751 static const DWORD ps_code[] =
2753 0xffff0101, /* ps_1_1 */
2754 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2755 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2756 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2757 0x00000042, 0xb00f0000, /* tex t0 */
2758 0x00000042, 0xb00f0001, /* tex t1 */
2759 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2760 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2761 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2762 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2763 0x0000ffff, /* end */
2769 float s1, t1, p1, q1;
2773 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2774 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2775 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2776 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2785 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2786 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2787 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2788 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2789 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2790 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2791 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2792 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2794 IDirect3DTexture8 *texture;
2797 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2798 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2799 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2800 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2803 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
2806 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2807 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2810 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
2813 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2814 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2817 skip("No INTZ support, skipping RESZ test.\n");
2820 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2821 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
2824 skip("No RESZ support, skipping RESZ test.\n");
2827 IDirect3D8_Release(d3d8);
2829 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2830 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2831 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2833 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2837 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2838 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2839 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2840 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2842 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2843 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2844 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2845 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2846 D3DMULTISAMPLE_2_SAMPLES, &ds);
2848 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2849 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2850 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2851 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
2852 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2854 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
2855 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2856 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
2857 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2859 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2860 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2861 IDirect3DSurface8_Release(intz_ds);
2862 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2863 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2865 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2866 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2867 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2868 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2869 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2870 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2871 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2872 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2873 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2874 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2875 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2877 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2878 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2879 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2880 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2881 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2882 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2883 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2884 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2886 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2887 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2888 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2889 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2890 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2891 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2892 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2893 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2894 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2895 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2896 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2897 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2898 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2900 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
2901 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2902 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2904 hr = IDirect3DDevice8_BeginScene(device);
2905 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2907 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2909 /* The destination depth texture has to be bound to sampler 0 */
2910 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2911 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2913 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
2914 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2915 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2916 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2918 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2919 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2920 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2921 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2922 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2923 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2924 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2925 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2926 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2927 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2929 /* The actual multisampled depth buffer resolve happens here */
2930 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2931 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2932 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
2933 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
2935 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2936 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2937 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2938 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2939 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2940 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2942 /* Read the depth values back. */
2943 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2944 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2945 hr = IDirect3DDevice8_EndScene(device);
2946 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2948 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2950 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2951 ok(color_match(color, expected_colors[i].color, 1),
2952 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2953 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2956 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2957 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2959 /* Test edge cases - try with no texture at all */
2960 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2961 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2962 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2963 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2964 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2965 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2967 hr = IDirect3DDevice8_BeginScene(device);
2968 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2969 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2970 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2971 hr = IDirect3DDevice8_EndScene(device);
2972 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2974 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2975 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2977 /* With a non-multisampled depth buffer */
2978 IDirect3DSurface8_Release(ds);
2979 IDirect3DSurface8_Release(rt);
2980 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2981 D3DMULTISAMPLE_NONE, &ds);
2983 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2984 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2985 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2986 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2988 hr = IDirect3DDevice8_BeginScene(device);
2989 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2990 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2991 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2992 hr = IDirect3DDevice8_EndScene(device);
2993 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2995 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2996 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2998 hr = IDirect3DDevice8_BeginScene(device);
2999 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3000 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3001 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3002 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3003 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
3005 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3006 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3007 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3008 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
3009 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3010 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3011 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
3013 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3014 hr = IDirect3DDevice8_EndScene(device);
3015 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3017 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3018 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3020 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3021 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3022 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3023 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3025 /* Read the depth values back. */
3026 hr = IDirect3DDevice8_BeginScene(device);
3027 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3028 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3029 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3030 hr = IDirect3DDevice8_EndScene(device);
3031 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3033 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3035 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3036 ok(color_match(color, expected_colors[i].color, 1),
3037 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3038 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3041 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3042 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3044 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
3045 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3046 IDirect3DSurface8_Release(ds);
3047 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3048 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3049 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3050 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3051 IDirect3DTexture8_Release(texture);
3052 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3053 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3054 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3055 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3056 IDirect3DSurface8_Release(original_ds);
3057 IDirect3DSurface8_Release(original_rt);
3060 static void zenable_test(IDirect3DDevice8 *device)
3064 struct vec4 position;
3069 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
3070 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
3071 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
3072 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
3080 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3081 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
3082 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3083 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3085 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3086 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3087 hr = IDirect3DDevice8_BeginScene(device);
3088 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3089 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
3090 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3091 hr = IDirect3DDevice8_EndScene(device);
3092 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3094 for (i = 0; i < 4; ++i)
3096 for (j = 0; j < 4; ++j)
3098 x = 80 * ((2 * j) + 1);
3099 y = 60 * ((2 * i) + 1);
3100 color = getPixelColor(device, x, y);
3101 ok(color_match(color, 0x0000ff00, 1),
3102 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
3106 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3107 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3109 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3110 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3112 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
3113 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3115 static const DWORD vs_code[] =
3117 0xfffe0101, /* vs_1_1 */
3118 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3119 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
3122 static const DWORD ps_code[] =
3124 0xffff0101, /* ps_1_1 */
3125 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
3126 0x0000ffff /* end */
3128 static const struct vec3 quad[] =
3130 {-1.0f, -1.0f, -0.5f},
3131 {-1.0f, 1.0f, -0.5f},
3132 { 1.0f, -1.0f, 1.5f},
3133 { 1.0f, 1.0f, 1.5f},
3135 static const D3DCOLOR expected[] =
3137 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
3138 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
3139 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
3140 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
3142 static const DWORD decl[] =
3145 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
3150 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
3151 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3152 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3153 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
3154 hr = IDirect3DDevice8_SetVertexShader(device, vs);
3155 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3156 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3157 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3159 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3160 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3161 hr = IDirect3DDevice8_BeginScene(device);
3162 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3163 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3164 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3165 hr = IDirect3DDevice8_EndScene(device);
3166 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3168 for (i = 0; i < 4; ++i)
3170 for (j = 0; j < 4; ++j)
3172 x = 80 * ((2 * j) + 1);
3173 y = 60 * ((2 * i) + 1);
3174 color = getPixelColor(device, x, y);
3175 ok(color_match(color, expected[i * 4 + j], 1),
3176 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
3180 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3181 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3183 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3184 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3185 hr = IDirect3DDevice8_SetVertexShader(device, 0);
3186 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3187 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3188 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
3189 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
3190 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
3196 IDirect3DDevice8 *device_ptr;
3201 d3d8_handle = LoadLibraryA("d3d8.dll");
3204 win_skip("Could not load d3d8.dll\n");
3208 device_ptr = init_d3d8();
3211 win_skip("Could not initialize direct3d\n");
3215 IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
3217 /* Check for the reliability of the returned data */
3218 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3221 skip("Clear failed, can't assure correctness of the test results\n");
3225 color = getPixelColor(device_ptr, 1, 1);
3226 if(color !=0x00ff0000)
3228 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3231 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3233 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3236 skip("Clear failed, can't assure correctness of the test results\n");
3240 color = getPixelColor(device_ptr, 639, 479);
3241 if(color != 0x0000ddee)
3243 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3246 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3248 /* Now run the real test */
3249 depth_clamp_test(device_ptr);
3250 lighting_test(device_ptr);
3251 clear_test(device_ptr);
3252 fog_test(device_ptr);
3253 present_test(device_ptr);
3254 offscreen_test(device_ptr);
3255 alpha_test(device_ptr);
3257 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3259 test_rcp_rsq(device_ptr);
3260 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
3261 fog_with_shader_test(device_ptr);
3265 skip("No vs.1.1 support\n");
3268 p8_texture_test(device_ptr);
3269 texop_test(device_ptr);
3270 depth_buffer_test(device_ptr);
3271 depth_buffer2_test(device_ptr);
3272 intz_test(device_ptr);
3273 shadow_test(device_ptr);
3274 multisample_copy_rects_test(device_ptr);
3275 zenable_test(device_ptr);
3276 resz_test(device_ptr);
3280 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
3283 IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
3284 DestroyWindow(creation_parameters.hFocusWindow);
3285 refcount = IDirect3DDevice8_Release(device_ptr);
3286 ok(!refcount, "Device has %u references left\n", refcount);