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 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 static void present_test(IDirect3DDevice8 *device)
634 struct vertex quad[] =
636 {-1.0f, -1.0f, 0.9f, 0xffff0000},
637 {-1.0f, 1.0f, 0.9f, 0xffff0000},
638 { 1.0f, -1.0f, 0.1f, 0xffff0000},
639 { 1.0f, 1.0f, 0.1f, 0xffff0000},
644 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
645 * then call Present. Then clear the color buffer to make sure it has some defined content
646 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
647 * by the depth value.
649 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
650 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
651 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
652 ok(SUCCEEDED(hr), "IDirect3DDevice8_Present returned %#x.\n", hr);
653 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4f, 0);
654 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear returned %#x.\n", hr);
656 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
657 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
658 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
659 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
660 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
661 ok(hr == D3D_OK, "IDirect3DDevice8_SetFVF returned %08x\n", hr);
663 hr = IDirect3DDevice8_BeginScene(device);
664 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %08x\n", hr);
667 /* No lights are defined... That means, lit vertices should be entirely black */
668 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
669 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %08x\n", hr);
671 hr = IDirect3DDevice8_EndScene(device);
672 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %08x\n", hr);
675 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
676 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
678 color = getPixelColor(device, 512, 240);
679 ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
680 color = getPixelColor(device, 64, 240);
681 ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
683 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
684 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
687 static void test_rcp_rsq(IDirect3DDevice8 *device)
692 float constant[4] = {1.0, 1.0, 1.0, 2.0};
694 static const float quad[][3] = {
695 {-1.0f, -1.0f, 0.0f},
697 { 1.0f, -1.0f, 0.0f},
701 const DWORD rcp_test[] = {
702 0xfffe0101, /* vs.1.1 */
704 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
705 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
706 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
707 0x00303030, /* enough to make windows happy */
709 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
710 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
714 const DWORD rsq_test[] = {
715 0xfffe0101, /* vs.1.1 */
717 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
718 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
719 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
720 0x00303030, /* enough to make windows happy */
722 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
723 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
730 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* D3DVSDE_POSITION, Register v0 */
734 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
735 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
737 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
738 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
740 IDirect3DDevice8_SetVertexShader(device, shader);
741 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
742 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
744 hr = IDirect3DDevice8_BeginScene(device);
745 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
748 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
749 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
750 hr = IDirect3DDevice8_EndScene(device);
751 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
754 color = getPixelColor(device, 320, 240);
755 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), 4),
756 "RCP test returned color 0x%08x, expected 0x00808080.\n", color);
758 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
759 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
761 IDirect3DDevice8_SetVertexShader(device, 0);
762 IDirect3DDevice8_DeleteVertexShader(device, shader);
764 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff996633, 0.0f, 0);
765 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
767 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
768 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
770 IDirect3DDevice8_SetVertexShader(device, shader);
771 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
772 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
774 hr = IDirect3DDevice8_BeginScene(device);
775 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
778 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
779 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
780 hr = IDirect3DDevice8_EndScene(device);
781 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
784 color = getPixelColor(device, 320, 240);
785 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), 4),
786 "RSQ test returned color 0x%08x, expected 0x00b4b4b4.\n", color);
788 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
789 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
791 IDirect3DDevice8_SetVertexShader(device, 0);
792 IDirect3DDevice8_DeleteVertexShader(device, shader);
795 static void offscreen_test(IDirect3DDevice8 *device)
798 IDirect3DTexture8 *offscreenTexture = NULL;
799 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
802 static const float quad[][5] = {
803 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
804 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
805 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
806 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
809 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
810 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
812 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
813 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
815 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
816 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
817 if(!offscreenTexture) {
818 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
819 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
820 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
821 if(!offscreenTexture) {
822 skip("Cannot create an offscreen render target\n");
827 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
828 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
833 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
834 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
839 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
840 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
842 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
843 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
844 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
845 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
846 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
847 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
848 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
849 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
850 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
851 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
853 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
854 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
855 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
856 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
857 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
859 /* Draw without textures - Should result in a white quad */
860 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
861 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
863 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
864 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
865 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
866 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
868 /* This time with the texture */
869 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
870 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
872 IDirect3DDevice8_EndScene(device);
875 /* Center quad - should be white */
876 color = getPixelColor(device, 320, 240);
877 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
878 /* Some quad in the cleared part of the texture */
879 color = getPixelColor(device, 170, 240);
880 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
881 /* Part of the originally cleared back buffer */
882 color = getPixelColor(device, 10, 10);
883 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
885 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
886 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
887 * the offscreen rendering mode this test would succeed or fail
889 color = getPixelColor(device, 10, 470);
890 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
893 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
896 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
897 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetTexture returned %#x.\n", hr);
901 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
902 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetRenderTarget returned %#x.\n", hr);
903 IDirect3DSurface8_Release(backbuffer);
905 if(offscreenTexture) {
906 IDirect3DTexture8_Release(offscreenTexture);
909 IDirect3DSurface8_Release(offscreen);
912 IDirect3DSurface8_Release(depthstencil);
916 static void alpha_test(IDirect3DDevice8 *device)
919 IDirect3DTexture8 *offscreenTexture;
920 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
923 struct vertex quad1[] =
925 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
926 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
927 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
928 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
930 struct vertex quad2[] =
932 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
933 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
934 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
935 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
937 static const float composite_quad[][5] = {
938 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
939 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
940 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
941 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
944 /* Clear the render target with alpha = 0.5 */
945 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
946 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
948 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
949 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
951 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
952 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
954 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
955 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
959 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
960 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
965 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
966 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
968 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
969 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
970 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
971 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
972 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
973 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
974 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
975 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
977 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
979 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
980 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
981 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
983 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
984 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
985 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
986 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
987 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
988 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
989 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
991 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
992 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
993 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
994 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
995 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
996 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
998 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
999 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
1000 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
1001 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
1002 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1003 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1004 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1007 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1008 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1009 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1010 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1011 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1013 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1014 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1015 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1016 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1017 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1018 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1020 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1021 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1023 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1024 * Disable alpha blending for the final composition
1026 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1027 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1028 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1029 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1031 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1032 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1033 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
1034 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1035 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1036 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1038 hr = IDirect3DDevice8_EndScene(device);
1039 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1042 color = getPixelColor(device, 160, 360);
1043 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1044 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
1046 color = getPixelColor(device, 160, 120);
1047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
1048 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
1050 color = getPixelColor(device, 480, 360);
1051 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1052 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
1054 color = getPixelColor(device, 480, 120);
1055 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1056 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
1058 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1061 /* restore things */
1063 IDirect3DSurface8_Release(backbuffer);
1065 if(offscreenTexture) {
1066 IDirect3DTexture8_Release(offscreenTexture);
1069 IDirect3DSurface8_Release(offscreen);
1072 IDirect3DSurface8_Release(depthstencil);
1076 static void p8_texture_test(IDirect3DDevice8 *device)
1078 IDirect3D8 *d3d = NULL;
1080 IDirect3DTexture8 *texture = NULL, *texture2 = NULL;
1082 unsigned char *data;
1083 DWORD color, red, green, blue;
1084 PALETTEENTRY table[256];
1088 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
1089 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
1090 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
1091 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
1094 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
1095 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
1096 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
1097 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
1100 IDirect3DDevice8_GetDirect3D(device, &d3d);
1102 if(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1103 D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK) {
1104 skip("D3DFMT_P8 textures not supported\n");
1108 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1109 D3DPOOL_MANAGED, &texture2);
1110 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1112 skip("Failed to create D3DFMT_P8 texture\n");
1116 memset(&lr, 0, sizeof(lr));
1117 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
1118 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1122 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
1123 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1125 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1126 D3DPOOL_MANAGED, &texture);
1127 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1129 skip("Failed to create D3DFMT_P8 texture\n");
1133 memset(&lr, 0, sizeof(lr));
1134 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
1135 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1139 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1140 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1142 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1143 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1145 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1146 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1148 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
1149 alpha of every entry is set to 1.0, which MS says is required when there's no
1150 D3DPTEXTURECAPS_ALPHAPALETTE capability */
1151 for (i = 0; i < 256; i++) {
1152 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1153 table[i].peFlags = 0xff;
1155 table[1].peRed = 0xff;
1156 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1157 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1160 table[1].peBlue = 0xff;
1161 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1162 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1164 hr = IDirect3DDevice8_BeginScene(device);
1165 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1167 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1168 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1169 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1170 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1172 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1173 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1175 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1176 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1178 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1179 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1180 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1181 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1183 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
1184 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1185 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1186 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1188 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1189 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1190 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1191 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1193 hr = IDirect3DDevice8_EndScene(device);
1194 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1197 color = getPixelColor(device, 32, 32);
1198 red = (color & 0x00ff0000) >> 16;
1199 green = (color & 0x0000ff00) >> 8;
1200 blue = (color & 0x000000ff) >> 0;
1201 ok(red == 0xff && blue == 0 && green == 0,
1202 "got color %08x, expected 0x00ff0000\n", color);
1204 color = getPixelColor(device, 32, 320);
1205 red = (color & 0x00ff0000) >> 16;
1206 green = (color & 0x0000ff00) >> 8;
1207 blue = (color & 0x000000ff) >> 0;
1208 ok(red == 0 && blue == 0xff && green == 0,
1209 "got color %08x, expected 0x000000ff\n", color);
1211 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1212 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1214 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1215 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1217 hr = IDirect3DDevice8_BeginScene(device);
1218 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1220 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1221 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1223 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1224 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1226 hr = IDirect3DDevice8_EndScene(device);
1227 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1231 color = getPixelColor(device, 32, 32);
1232 red = (color & 0x00ff0000) >> 16;
1233 green = (color & 0x0000ff00) >> 8;
1234 blue = (color & 0x000000ff) >> 0;
1235 ok(red == 0 && blue == 0xff && green == 0,
1236 "got color %08x, expected 0x000000ff\n", color);
1238 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1239 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1241 /* Test palettes with alpha */
1242 IDirect3DDevice8_GetDeviceCaps(device, &caps);
1243 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
1244 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
1246 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1247 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1249 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1250 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1252 for (i = 0; i < 256; i++) {
1253 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1254 table[i].peFlags = 0xff;
1256 table[1].peRed = 0xff;
1257 table[1].peFlags = 0x80;
1258 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1259 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1262 table[1].peBlue = 0xff;
1263 table[1].peFlags = 0x80;
1264 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1265 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1267 hr = IDirect3DDevice8_BeginScene(device);
1268 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1270 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1271 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1272 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1273 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1275 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1276 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1278 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1279 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1281 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1282 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1284 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1285 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1287 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1288 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1290 hr = IDirect3DDevice8_EndScene(device);
1291 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1294 color = getPixelColor(device, 32, 32);
1295 red = (color & 0x00ff0000) >> 16;
1296 green = (color & 0x0000ff00) >> 8;
1297 blue = (color & 0x000000ff) >> 0;
1298 ok(red >= 0x7e && red <= 0x81 && blue == 0 && green == 0,
1299 "got color %08x, expected 0x00800000 or near\n", color);
1301 color = getPixelColor(device, 32, 320);
1302 red = (color & 0x00ff0000) >> 16;
1303 green = (color & 0x0000ff00) >> 8;
1304 blue = (color & 0x000000ff) >> 0;
1305 ok(red == 0 && blue >= 0x7e && blue <= 0x81 && green == 0,
1306 "got color %08x, expected 0x00000080 or near\n", color);
1308 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1309 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1312 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1313 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1314 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1315 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1318 if(texture) IDirect3DTexture8_Release(texture);
1319 if(texture2) IDirect3DTexture8_Release(texture2);
1320 IDirect3D8_Release(d3d);
1323 static void texop_test(IDirect3DDevice8 *device)
1325 IDirect3DTexture8 *texture = NULL;
1326 D3DLOCKED_RECT locked_rect;
1332 static const struct {
1337 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
1338 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
1339 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
1340 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
1343 static const struct {
1349 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1350 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
1351 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
1352 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
1353 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1354 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1356 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
1357 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1359 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1360 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1361 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1362 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
1363 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
1364 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1365 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1366 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
1367 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
1368 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1369 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
1370 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
1371 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
1372 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
1373 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
1376 memset(&caps, 0, sizeof(caps));
1377 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1378 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
1380 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
1381 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
1383 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
1384 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
1385 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
1386 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1387 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
1388 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1389 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1390 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1391 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1393 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
1394 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1395 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1396 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1397 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
1398 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1400 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
1401 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1403 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1404 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1405 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
1406 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1407 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
1408 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1410 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1411 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1413 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1415 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
1417 skip("tex operation %s not supported\n", test_data[i].name);
1421 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
1422 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
1424 hr = IDirect3DDevice8_BeginScene(device);
1425 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
1427 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1428 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
1430 hr = IDirect3DDevice8_EndScene(device);
1431 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
1433 color = getPixelColor(device, 320, 240);
1434 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
1435 test_data[i].name, color, test_data[i].result);
1437 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1438 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
1440 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1441 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1444 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1445 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1446 if (texture) IDirect3DTexture8_Release(texture);
1449 /* This test tests depth clamping / clipping behaviour:
1450 * - With software vertex processing, depth values are clamped to the
1451 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
1452 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
1453 * same as regular vertices here.
1454 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
1455 * Normal vertices are always clipped. Pretransformed vertices are
1456 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
1457 * - The viewport's MinZ/MaxZ is irrelevant for this.
1459 static void depth_clamp_test(IDirect3DDevice8 *device)
1461 const struct tvertex quad1[] =
1463 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1464 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1465 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1466 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1468 const struct tvertex quad2[] =
1470 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1471 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1472 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1473 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1475 const struct tvertex quad3[] =
1477 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1478 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1479 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1480 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1482 const struct tvertex quad4[] =
1484 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1485 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1486 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1487 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1489 const struct vertex quad5[] =
1491 { -0.5f, 0.5f, 10.0f, 0xff14f914},
1492 { 0.5f, 0.5f, 10.0f, 0xff14f914},
1493 { -0.5f, -0.5f, 10.0f, 0xff14f914},
1494 { 0.5f, -0.5f, 10.0f, 0xff14f914},
1496 const struct vertex quad6[] =
1498 { -1.0f, 0.5f, 10.0f, 0xfff91414},
1499 { 1.0f, 0.5f, 10.0f, 0xfff91414},
1500 { -1.0f, 0.25f, 10.0f, 0xfff91414},
1501 { 1.0f, 0.25f, 10.0f, 0xfff91414},
1516 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1517 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1519 hr = IDirect3DDevice8_SetViewport(device, &vp);
1520 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1522 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
1523 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1525 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1526 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1527 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1528 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1529 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1530 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1531 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1532 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1534 hr = IDirect3DDevice8_BeginScene(device);
1535 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1537 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1538 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
1540 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1541 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1542 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1543 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1545 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1546 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1548 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1549 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1550 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
1551 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1553 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1554 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1555 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1556 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1558 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
1559 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1561 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1562 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1564 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
1565 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1567 hr = IDirect3DDevice8_EndScene(device);
1568 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1570 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1572 color = getPixelColor(device, 75, 75);
1573 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1574 color = getPixelColor(device, 150, 150);
1575 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1576 color = getPixelColor(device, 320, 240);
1577 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1578 color = getPixelColor(device, 320, 330);
1579 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1580 color = getPixelColor(device, 320, 330);
1581 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1585 color = getPixelColor(device, 75, 75);
1586 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1587 color = getPixelColor(device, 150, 150);
1588 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1589 color = getPixelColor(device, 320, 240);
1590 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
1591 color = getPixelColor(device, 320, 330);
1592 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1593 color = getPixelColor(device, 320, 330);
1594 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1597 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1598 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1602 hr = IDirect3DDevice8_SetViewport(device, &vp);
1603 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1606 static void depth_buffer_test(IDirect3DDevice8 *device)
1608 static const struct vertex quad1[] =
1610 { -1.0, 1.0, 0.33f, 0xff00ff00},
1611 { 1.0, 1.0, 0.33f, 0xff00ff00},
1612 { -1.0, -1.0, 0.33f, 0xff00ff00},
1613 { 1.0, -1.0, 0.33f, 0xff00ff00},
1615 static const struct vertex quad2[] =
1617 { -1.0, 1.0, 0.50f, 0xffff00ff},
1618 { 1.0, 1.0, 0.50f, 0xffff00ff},
1619 { -1.0, -1.0, 0.50f, 0xffff00ff},
1620 { 1.0, -1.0, 0.50f, 0xffff00ff},
1622 static const struct vertex quad3[] =
1624 { -1.0, 1.0, 0.66f, 0xffff0000},
1625 { 1.0, 1.0, 0.66f, 0xffff0000},
1626 { -1.0, -1.0, 0.66f, 0xffff0000},
1627 { 1.0, -1.0, 0.66f, 0xffff0000},
1629 static const DWORD expected_colors[4][4] =
1631 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1632 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1633 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
1634 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
1637 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
1638 IDirect3DSurface8 *depth_stencil;
1651 hr = IDirect3DDevice8_SetViewport(device, &vp);
1652 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1654 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1655 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1656 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1657 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1658 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1659 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1660 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1661 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1662 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1663 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1665 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1666 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1667 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1668 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1669 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
1670 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1671 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1672 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1673 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1674 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1675 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1676 D3DMULTISAMPLE_NONE, FALSE, &rt3);
1677 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1679 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
1680 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1681 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
1682 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1684 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1685 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1686 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1687 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1689 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1690 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1691 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1692 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1694 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1695 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1696 hr = IDirect3DDevice8_BeginScene(device);
1697 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1698 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1699 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1700 hr = IDirect3DDevice8_EndScene(device);
1701 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1703 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1704 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1705 IDirect3DSurface8_Release(depth_stencil);
1706 IDirect3DSurface8_Release(backbuffer);
1707 IDirect3DSurface8_Release(rt3);
1708 IDirect3DSurface8_Release(rt2);
1709 IDirect3DSurface8_Release(rt1);
1711 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1712 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1714 hr = IDirect3DDevice8_BeginScene(device);
1715 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1716 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1717 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1718 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1719 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1720 hr = IDirect3DDevice8_EndScene(device);
1721 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1723 for (i = 0; i < 4; ++i)
1725 for (j = 0; j < 4; ++j)
1727 unsigned int x = 80 * ((2 * j) + 1);
1728 unsigned int y = 60 * ((2 * i) + 1);
1729 color = getPixelColor(device, x, y);
1730 ok(color_match(color, expected_colors[i][j], 0),
1731 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
1735 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1736 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1739 /* Test that partial depth copies work the way they're supposed to. The clear
1740 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
1741 * the following draw should only copy back the part that was modified. */
1742 static void depth_buffer2_test(IDirect3DDevice8 *device)
1744 static const struct vertex quad[] =
1746 { -1.0, 1.0, 0.66f, 0xffff0000},
1747 { 1.0, 1.0, 0.66f, 0xffff0000},
1748 { -1.0, -1.0, 0.66f, 0xffff0000},
1749 { 1.0, -1.0, 0.66f, 0xffff0000},
1752 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
1753 IDirect3DSurface8 *depth_stencil;
1766 hr = IDirect3DDevice8_SetViewport(device, &vp);
1767 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1769 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1770 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1771 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1772 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1773 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1774 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1775 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1776 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1777 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1778 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1780 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1781 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1782 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1783 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1784 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1785 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1786 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1787 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1788 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1789 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1791 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1792 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1793 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1794 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1796 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1797 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1798 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
1799 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1801 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1802 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1803 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1804 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1806 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1807 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1808 IDirect3DSurface8_Release(depth_stencil);
1809 IDirect3DSurface8_Release(backbuffer);
1810 IDirect3DSurface8_Release(rt2);
1811 IDirect3DSurface8_Release(rt1);
1813 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1814 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1816 hr = IDirect3DDevice8_BeginScene(device);
1817 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1818 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1819 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1820 hr = IDirect3DDevice8_EndScene(device);
1821 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1823 for (i = 0; i < 4; ++i)
1825 for (j = 0; j < 4; ++j)
1827 unsigned int x = 80 * ((2 * j) + 1);
1828 unsigned int y = 60 * ((2 * i) + 1);
1829 color = getPixelColor(device, x, y);
1830 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
1831 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
1835 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1836 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1839 static void intz_test(IDirect3DDevice8 *device)
1841 static const DWORD ps_code[] =
1843 0xffff0101, /* ps_1_1 */
1844 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
1845 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
1846 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
1847 0x00000042, 0xb00f0000, /* tex t0 */
1848 0x00000042, 0xb00f0001, /* tex t1 */
1849 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
1850 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
1851 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
1852 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
1853 0x0000ffff, /* end */
1859 float s1, t1, p1, q1;
1863 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1864 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1865 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1866 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1870 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1871 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1872 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1873 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1877 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1878 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1879 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1880 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1889 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
1890 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
1891 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
1892 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
1893 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
1894 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
1895 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
1896 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
1899 IDirect3DSurface8 *original_ds, *original_rt, *rt;
1900 IDirect3DTexture8 *texture;
1901 IDirect3DSurface8 *ds;
1908 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1909 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1910 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1912 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
1915 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
1917 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
1921 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
1922 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
1924 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1925 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
1928 skip("No INTZ support, skipping INTZ test.\n");
1932 IDirect3D8_Release(d3d8);
1934 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
1935 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1936 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
1937 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1939 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
1940 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
1941 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
1942 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1943 D3DMULTISAMPLE_NONE, FALSE, &rt);
1944 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1945 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
1946 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
1948 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
1949 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
1950 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1951 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1952 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
1954 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1955 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1956 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1957 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1958 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1960 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1961 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1962 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
1963 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1964 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1965 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1966 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
1967 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1969 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1970 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1971 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1972 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1973 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1974 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1975 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
1976 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1977 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
1978 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1979 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
1980 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
1981 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1983 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
1984 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
1986 /* Render offscreen, using the INTZ texture as depth buffer */
1987 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
1988 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1989 IDirect3DDevice8_SetPixelShader(device, 0);
1990 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
1992 /* Setup the depth/stencil surface. */
1993 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
1994 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1996 hr = IDirect3DDevice8_BeginScene(device);
1997 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1998 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2000 hr = IDirect3DDevice8_EndScene(device);
2001 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2003 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2004 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2005 IDirect3DSurface8_Release(ds);
2006 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2007 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2008 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2009 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2010 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2011 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2013 /* Read the depth values back. */
2014 hr = IDirect3DDevice8_BeginScene(device);
2015 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2016 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2017 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2018 hr = IDirect3DDevice8_EndScene(device);
2019 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2021 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2023 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2024 ok(color_match(color, expected_colors[i].color, 1),
2025 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2026 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2029 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2030 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2032 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2033 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2034 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2035 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2036 IDirect3DTexture8_Release(texture);
2038 /* Render onscreen while using the INTZ texture as depth buffer */
2039 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2040 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2041 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2042 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2043 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2044 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2045 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2046 IDirect3DDevice8_SetPixelShader(device, 0);
2047 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2049 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2050 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2052 hr = IDirect3DDevice8_BeginScene(device);
2053 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2054 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2055 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2056 hr = IDirect3DDevice8_EndScene(device);
2057 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2059 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2060 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2061 IDirect3DSurface8_Release(ds);
2062 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2063 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2064 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2065 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2066 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2067 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2069 /* Read the depth values back. */
2070 hr = IDirect3DDevice8_BeginScene(device);
2071 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2072 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2073 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2074 hr = IDirect3DDevice8_EndScene(device);
2075 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2077 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2079 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2080 ok(color_match(color, expected_colors[i].color, 1),
2081 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2082 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2085 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2086 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2088 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2089 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2090 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2091 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2092 IDirect3DTexture8_Release(texture);
2094 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
2095 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2096 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2097 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2098 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2099 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2100 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2101 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2102 IDirect3DDevice8_SetPixelShader(device, 0);
2103 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2105 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2106 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2108 hr = IDirect3DDevice8_BeginScene(device);
2109 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2110 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
2111 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2112 hr = IDirect3DDevice8_EndScene(device);
2113 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2115 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2116 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2118 hr = IDirect3DDevice8_BeginScene(device);
2119 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2120 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
2121 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2122 hr = IDirect3DDevice8_EndScene(device);
2123 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2125 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2126 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2127 IDirect3DSurface8_Release(ds);
2128 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2129 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2130 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2131 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2132 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2133 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2135 /* Read the depth values back. */
2136 hr = IDirect3DDevice8_BeginScene(device);
2137 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2138 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2139 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2140 hr = IDirect3DDevice8_EndScene(device);
2141 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2143 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2145 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2146 ok(color_match(color, expected_colors[i].color, 1),
2147 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2148 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2151 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2152 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2154 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2155 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2156 IDirect3DSurface8_Release(original_ds);
2157 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2158 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2159 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2160 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2161 IDirect3DTexture8_Release(texture);
2162 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2163 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2164 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2165 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2167 IDirect3DSurface8_Release(original_rt);
2168 IDirect3DSurface8_Release(rt);
2171 static void shadow_test(IDirect3DDevice8 *device)
2173 static const DWORD ps_code[] =
2175 0xffff0101, /* ps_1_1 */
2176 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2177 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2178 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2179 0x00000042, 0xb00f0000, /* tex t0 */
2180 0x00000042, 0xb00f0001, /* tex t1 */
2181 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2182 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2183 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2184 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2185 0x0000ffff, /* end */
2194 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
2195 {D3DFMT_D32, "D3DFMT_D32"},
2196 {D3DFMT_D15S1, "D3DFMT_D15S1"},
2197 {D3DFMT_D24S8, "D3DFMT_D24S8"},
2198 {D3DFMT_D24X8, "D3DFMT_D24X8"},
2199 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
2200 {D3DFMT_D16, "D3DFMT_D16"},
2206 float s1, t1, p1, q1;
2210 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2211 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2212 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2213 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2222 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2223 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2224 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2225 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2226 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2227 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2228 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2229 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2232 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2239 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2240 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2241 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2243 skip("No pixel shader 1.1 support, skipping shadow test.\n");
2247 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2248 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2249 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2250 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2251 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2252 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2254 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2255 D3DMULTISAMPLE_NONE, FALSE, &rt);
2256 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2257 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2258 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2260 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2261 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2262 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2263 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2264 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2265 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2266 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2268 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2269 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2270 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2272 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2273 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2274 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2275 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2276 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2277 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2278 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2279 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2281 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2282 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2283 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2284 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2285 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2286 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2287 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2288 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2289 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2290 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2291 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2292 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2293 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2295 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2297 D3DFORMAT format = formats[i].format;
2298 IDirect3DTexture8 *texture;
2299 IDirect3DSurface8 *ds;
2302 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2303 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2304 if (FAILED(hr)) continue;
2306 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2307 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2308 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2310 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2311 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2313 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2314 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2316 IDirect3DDevice8_SetPixelShader(device, 0);
2317 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2319 /* Setup the depth/stencil surface. */
2320 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2321 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2323 hr = IDirect3DDevice8_BeginScene(device);
2324 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2325 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2326 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2327 hr = IDirect3DDevice8_EndScene(device);
2328 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2330 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2331 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2332 IDirect3DSurface8_Release(ds);
2334 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2335 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2336 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2337 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2339 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2340 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2342 /* Do the actual shadow mapping. */
2343 hr = IDirect3DDevice8_BeginScene(device);
2344 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2345 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2346 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2347 hr = IDirect3DDevice8_EndScene(device);
2348 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2350 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2351 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2352 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2353 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2354 IDirect3DTexture8_Release(texture);
2356 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2358 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2359 ok(color_match(color, expected_colors[j].color, 0),
2360 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2361 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2362 formats[i].name, color);
2365 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2366 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2369 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2370 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2371 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2372 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2374 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2375 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2376 IDirect3DSurface8_Release(original_ds);
2378 IDirect3DSurface8_Release(original_rt);
2379 IDirect3DSurface8_Release(rt);
2381 IDirect3D8_Release(d3d8);
2384 static void multisample_copy_rects_test(IDirect3DDevice8 *device)
2386 IDirect3DSurface8 *original_ds, *original_rt, *ds, *ds_plain, *rt, *readback;
2387 RECT src_rect = {64, 64, 128, 128};
2388 POINT dst_point = {96, 96};
2389 D3DLOCKED_RECT locked_rect;
2394 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2395 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2396 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2397 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2398 IDirect3D8_Release(d3d8);
2401 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
2405 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
2406 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2407 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2408 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2409 D3DMULTISAMPLE_2_SAMPLES, &ds);
2410 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2411 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2412 D3DMULTISAMPLE_NONE, &ds_plain);
2413 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2414 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
2415 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
2417 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2418 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2419 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2420 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2422 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2423 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2425 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2426 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2428 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
2429 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2431 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
2432 todo_wine ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2434 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2435 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2437 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
2438 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2440 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
2441 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
2443 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
2444 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2446 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
2447 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
2449 hr = IDirect3DSurface8_UnlockRect(readback);
2450 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
2452 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2453 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
2455 IDirect3DSurface8_Release(original_ds);
2456 IDirect3DSurface8_Release(original_rt);
2457 IDirect3DSurface8_Release(readback);
2458 IDirect3DSurface8_Release(ds_plain);
2459 IDirect3DSurface8_Release(ds);
2460 IDirect3DSurface8_Release(rt);
2463 static void resz_test(IDirect3DDevice8 *device)
2465 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
2470 static const DWORD ps_code[] =
2472 0xffff0101, /* ps_1_1 */
2473 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2474 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2475 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2476 0x00000042, 0xb00f0000, /* tex t0 */
2477 0x00000042, 0xb00f0001, /* tex t1 */
2478 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2479 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2480 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2481 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2482 0x0000ffff, /* end */
2488 float s1, t1, p1, q1;
2492 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2493 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2494 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2495 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2504 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2505 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2506 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2507 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2508 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2509 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2510 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2511 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2513 IDirect3DTexture8 *texture;
2516 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2517 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2518 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2519 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2522 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
2525 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2526 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2529 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
2532 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2533 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2536 skip("No INTZ support, skipping RESZ test.\n");
2539 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2540 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
2543 skip("No RESZ support, skipping RESZ test.\n");
2546 IDirect3D8_Release(d3d8);
2548 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2549 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2550 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2552 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2556 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2557 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2558 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2559 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2561 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2562 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2563 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2564 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2565 D3DMULTISAMPLE_2_SAMPLES, &ds);
2567 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2568 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2569 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2570 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
2571 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2573 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
2574 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2575 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
2576 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2578 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2579 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2580 IDirect3DSurface8_Release(intz_ds);
2581 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2582 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2584 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2585 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2586 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2587 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2588 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2589 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2590 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2591 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2592 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2593 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2594 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2596 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2597 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2598 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2599 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2600 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2601 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2602 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2603 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2605 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2606 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2607 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2608 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2609 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2610 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2611 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2612 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2613 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2614 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2615 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2616 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2617 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2619 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
2620 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2621 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2623 hr = IDirect3DDevice8_BeginScene(device);
2624 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2625 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2626 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2628 /* The destination depth texture has to be bound to sampler 0 */
2629 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2630 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2632 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
2633 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2634 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2635 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2636 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2637 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2638 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2639 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2640 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2641 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2642 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2643 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2644 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2645 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2646 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2648 /* The actual multisampled depth buffer resolve happens here */
2649 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2650 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2651 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
2652 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
2654 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2655 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2656 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2657 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2658 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2659 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2661 /* Read the depth values back. */
2662 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2663 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2664 hr = IDirect3DDevice8_EndScene(device);
2665 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2667 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2669 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2670 ok(color_match(color, expected_colors[i].color, 1),
2671 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2672 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2675 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2676 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2678 /* Test edge cases - try with no texture at all */
2679 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2680 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2681 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2682 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2683 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2684 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2686 hr = IDirect3DDevice8_BeginScene(device);
2687 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2688 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2689 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2690 hr = IDirect3DDevice8_EndScene(device);
2691 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2693 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2694 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2696 /* With a non-multisampled depth buffer */
2697 IDirect3DSurface8_Release(ds);
2698 IDirect3DSurface8_Release(rt);
2699 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2700 D3DMULTISAMPLE_NONE, &ds);
2702 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2703 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2704 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2705 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2707 hr = IDirect3DDevice8_BeginScene(device);
2708 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2709 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2710 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2711 hr = IDirect3DDevice8_EndScene(device);
2712 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2714 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2715 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2717 hr = IDirect3DDevice8_BeginScene(device);
2718 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2719 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2720 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2721 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2722 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2723 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2724 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2725 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2726 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2727 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2728 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2729 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2730 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2731 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2732 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2733 hr = IDirect3DDevice8_EndScene(device);
2734 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2736 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2737 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2739 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2740 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2741 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2742 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2744 /* Read the depth values back. */
2745 hr = IDirect3DDevice8_BeginScene(device);
2746 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2747 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2748 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2749 hr = IDirect3DDevice8_EndScene(device);
2750 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2752 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2754 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2755 ok(color_match(color, expected_colors[i].color, 1),
2756 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2757 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2760 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2761 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2763 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2764 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2765 IDirect3DSurface8_Release(ds);
2766 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2767 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2768 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2769 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2770 IDirect3DTexture8_Release(texture);
2771 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2772 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2773 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2774 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2775 IDirect3DSurface8_Release(original_ds);
2776 IDirect3DSurface8_Release(original_rt);
2779 static void zenable_test(IDirect3DDevice8 *device)
2783 struct vec4 position;
2788 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
2789 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
2790 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
2791 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
2799 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2800 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
2801 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2802 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2804 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
2805 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2806 hr = IDirect3DDevice8_BeginScene(device);
2807 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2808 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
2809 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2810 hr = IDirect3DDevice8_EndScene(device);
2811 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2813 for (i = 0; i < 4; ++i)
2815 for (j = 0; j < 4; ++j)
2817 x = 80 * ((2 * j) + 1);
2818 y = 60 * ((2 * i) + 1);
2819 color = getPixelColor(device, x, y);
2820 ok(color_match(color, 0x0000ff00, 1),
2821 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
2825 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2826 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
2828 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2829 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2831 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
2832 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
2834 static const DWORD vs_code[] =
2836 0xfffe0101, /* vs_1_1 */
2837 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2838 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
2841 static const DWORD ps_code[] =
2843 0xffff0101, /* ps_1_1 */
2844 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2845 0x0000ffff /* end */
2847 static const struct vec3 quad[] =
2849 {-1.0f, -1.0f, -0.5f},
2850 {-1.0f, 1.0f, -0.5f},
2851 { 1.0f, -1.0f, 1.5f},
2852 { 1.0f, 1.0f, 1.5f},
2854 static const D3DCOLOR expected[] =
2856 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
2857 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
2858 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
2859 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
2861 static const DWORD decl[] =
2864 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2869 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
2870 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2871 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2872 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
2873 hr = IDirect3DDevice8_SetVertexShader(device, vs);
2874 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2875 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2876 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
2878 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
2879 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2880 hr = IDirect3DDevice8_BeginScene(device);
2881 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2882 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2883 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2884 hr = IDirect3DDevice8_EndScene(device);
2885 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2887 for (i = 0; i < 4; ++i)
2889 for (j = 0; j < 4; ++j)
2891 x = 80 * ((2 * j) + 1);
2892 y = 60 * ((2 * i) + 1);
2893 color = getPixelColor(device, x, y);
2894 ok(color_match(color, expected[i * 4 + j], 1),
2895 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
2899 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2900 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
2902 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2903 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
2904 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2905 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2907 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
2908 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
2909 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2915 IDirect3DDevice8 *device_ptr;
2920 d3d8_handle = LoadLibraryA("d3d8.dll");
2923 win_skip("Could not load d3d8.dll\n");
2927 device_ptr = init_d3d8();
2930 win_skip("Could not initialize direct3d\n");
2934 IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
2936 /* Check for the reliability of the returned data */
2937 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2940 skip("Clear failed, can't assure correctness of the test results\n");
2944 color = getPixelColor(device_ptr, 1, 1);
2945 if(color !=0x00ff0000)
2947 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
2950 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
2952 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
2955 skip("Clear failed, can't assure correctness of the test results\n");
2959 color = getPixelColor(device_ptr, 639, 479);
2960 if(color != 0x0000ddee)
2962 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
2965 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
2967 /* Now run the real test */
2968 depth_clamp_test(device_ptr);
2969 lighting_test(device_ptr);
2970 clear_test(device_ptr);
2971 fog_test(device_ptr);
2972 present_test(device_ptr);
2973 offscreen_test(device_ptr);
2974 alpha_test(device_ptr);
2976 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
2978 test_rcp_rsq(device_ptr);
2982 skip("No vs.1.1 support\n");
2985 p8_texture_test(device_ptr);
2986 texop_test(device_ptr);
2987 depth_buffer_test(device_ptr);
2988 depth_buffer2_test(device_ptr);
2989 intz_test(device_ptr);
2990 shadow_test(device_ptr);
2991 multisample_copy_rects_test(device_ptr);
2992 zenable_test(device_ptr);
2993 resz_test(device_ptr);
2997 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
3000 IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
3001 DestroyWindow(creation_parameters.hFocusWindow);
3002 refcount = IDirect3DDevice8_Release(device_ptr);
3003 ok(!refcount, "Device has %u references left\n", refcount);