2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
24 #include "wine/test.h"
26 static HMODULE d3d8_handle = 0;
38 static HWND create_window(void)
42 wc.lpfnWndProc = DefWindowProc;
43 wc.lpszClassName = "d3d8_test_wc";
46 ret = CreateWindow("d3d8_test_wc", "d3d8_test",
47 WS_POPUP | WS_SYSMENU , 20, 20, 640, 480, 0, 0, 0, 0);
48 ShowWindow(ret, SW_SHOW);
52 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
67 IDirect3DTexture8 *tex = NULL;
68 IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
70 D3DLOCKED_RECT lockedRect;
71 RECT rectToLock = {x, y, x+1, y+1};
73 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
74 if(FAILED(hr) || !tex ) /* This is not a test */
76 trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr);
79 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &surf);
80 if(FAILED(hr) || !tex ) /* This is not a test */
82 trace("Can't get surface from texture, hr=%#08x\n", hr);
87 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
90 trace("Can't get the render target, hr=%#08x\n", hr);
94 hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
97 trace("Can't read the render target, hr=%#08x\n", hr);
102 hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
105 trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
109 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
110 * really important for these tests
112 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
113 hr = IDirect3DSurface8_UnlockRect(surf);
116 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
120 if(backbuf) IDirect3DSurface8_Release(backbuf);
121 if(surf) IDirect3DSurface8_Release(surf);
122 if(tex) IDirect3DTexture8_Release(tex);
126 static IDirect3DDevice8 *init_d3d8(void)
128 IDirect3D8 * (__stdcall * d3d8_create)(UINT SDKVersion) = 0;
129 IDirect3D8 *d3d8_ptr = 0;
130 IDirect3DDevice8 *device_ptr = 0;
131 D3DPRESENT_PARAMETERS present_parameters;
134 d3d8_create = (void *)GetProcAddress(d3d8_handle, "Direct3DCreate8");
135 ok(d3d8_create != NULL, "Failed to get address of Direct3DCreate8\n");
136 if (!d3d8_create) return NULL;
138 d3d8_ptr = d3d8_create(D3D_SDK_VERSION);
141 skip("could not create D3D8\n");
145 ZeroMemory(&present_parameters, sizeof(present_parameters));
146 present_parameters.Windowed = TRUE;
147 present_parameters.hDeviceWindow = create_window();
148 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
149 present_parameters.BackBufferWidth = 640;
150 present_parameters.BackBufferHeight = 480;
151 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
152 present_parameters.EnableAutoDepthStencil = TRUE;
153 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
155 hr = IDirect3D8_CreateDevice(d3d8_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
156 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
157 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL || broken(hr == D3DERR_NOTAVAILABLE), "IDirect3D_CreateDevice returned: %#08x\n", hr);
181 static void lighting_test(IDirect3DDevice8 *device)
184 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
185 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
188 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
189 0.0f, 1.0f, 0.0f, 0.0f,
190 0.0f, 0.0f, 1.0f, 0.0f,
191 0.0f, 0.0f, 0.0f, 1.0f };
193 struct vertex unlitquad[] =
195 {-1.0f, -1.0f, 0.1f, 0xffff0000},
196 {-1.0f, 0.0f, 0.1f, 0xffff0000},
197 { 0.0f, 0.0f, 0.1f, 0xffff0000},
198 { 0.0f, -1.0f, 0.1f, 0xffff0000},
200 struct vertex litquad[] =
202 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
203 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
204 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
205 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
207 struct nvertex unlitnquad[] =
209 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
210 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
211 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
212 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
214 struct nvertex litnquad[] =
216 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
217 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
218 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
219 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
221 WORD Indices[] = {0, 1, 2, 2, 3, 0};
223 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
224 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
226 /* Setup some states that may cause issues */
227 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
228 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
229 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
230 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
231 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
232 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
233 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
234 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
235 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
236 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
237 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
238 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
239 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
240 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
241 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
242 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
243 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
244 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
245 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
246 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
247 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
248 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
250 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
251 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
253 hr = IDirect3DDevice8_BeginScene(device);
254 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr);
257 /* No lights are defined... That means, lit vertices should be entirely black */
258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
259 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
260 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
261 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
262 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
265 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
266 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
267 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
268 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
270 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
271 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed with %#08x\n", hr);
273 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
274 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
275 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
276 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
277 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
279 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
280 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
281 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
282 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
283 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
285 hr = IDirect3DDevice8_EndScene(device);
286 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %#08x\n", hr);
289 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
290 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
291 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
292 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
293 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
294 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
295 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
296 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
298 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
300 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
301 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
304 static void clear_test(IDirect3DDevice8 *device)
306 /* Tests the correctness of clearing parameters */
312 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
313 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
315 /* Positive x, negative y */
321 /* Positive x, positive y */
326 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
327 * is ignored, the positive is still cleared afterwards
329 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
330 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
332 /* negative x, negative y */
333 rect_negneg.x1 = 640;
334 rect_negneg.y1 = 240;
335 rect_negneg.x2 = 320;
337 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
338 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
340 color = getPixelColor(device, 160, 360); /* lower left quad */
341 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
342 color = getPixelColor(device, 160, 120); /* upper left quad */
343 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
344 color = getPixelColor(device, 480, 360); /* lower right quad */
345 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
346 color = getPixelColor(device, 480, 120); /* upper right quad */
347 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
349 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
351 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
352 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
358 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
359 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
361 color = getPixelColor(device, 320, 240);
362 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
363 "Clear with count = 0, rect != NULL has color %#08x\n", color);
365 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
367 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
368 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
369 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
370 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
372 color = getPixelColor(device, 320, 240);
373 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
374 "Clear with count = 1, rect = NULL has color %#08x\n", color);
376 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
391 static void fog_test(IDirect3DDevice8 *device)
395 float start = 0.0, end = 1.0;
397 /* Gets full z based fog with linear fog, no fog with specular color */
398 struct sVertex untransformed_1[] = {
399 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
400 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
401 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
402 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
404 /* Ok, I am too lazy to deal with transform matrices */
405 struct sVertex untransformed_2[] = {
406 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
407 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
408 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
409 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
411 /* Untransformed ones. Give them a different diffuse color to make the test look
412 * nicer. It also makes making sure that they are drawn correctly easier.
414 struct sVertexT transformed_1[] = {
415 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
416 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
417 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
418 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
420 struct sVertexT transformed_2[] = {
421 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
422 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
423 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
424 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
426 WORD Indices[] = {0, 1, 2, 2, 3, 0};
429 float ident_mat[16] =
431 1.0f, 0.0f, 0.0f, 0.0f,
432 0.0f, 1.0f, 0.0f, 0.0f,
433 0.0f, 0.0f, 1.0f, 0.0f,
434 0.0f, 0.0f, 0.0f, 1.0f
436 float world_mat1[16] =
438 1.0f, 0.0f, 0.0f, 0.0f,
439 0.0f, 1.0f, 0.0f, 0.0f,
440 0.0f, 0.0f, 1.0f, 0.0f,
441 0.0f, 0.0f, -0.5f, 1.0f
443 float world_mat2[16] =
445 1.0f, 0.0f, 0.0f, 0.0f,
446 0.0f, 1.0f, 0.0f, 0.0f,
447 0.0f, 0.0f, 1.0f, 0.0f,
448 0.0f, 0.0f, 1.0f, 1.0f
452 1.0f, 0.0f, 0.0f, 0.0f,
453 0.0f, 1.0f, 0.0f, 0.0f,
454 0.0f, 0.0f, 1.0f, 0.0f,
455 0.0f, 0.0f, -1.0f, 1.0f
458 struct sVertex far_quad1[] =
460 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
461 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
462 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
463 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
465 struct sVertex far_quad2[] =
467 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
468 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
469 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
470 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
473 memset(&caps, 0, sizeof(caps));
474 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
475 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
477 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
478 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
480 /* Setup initial states: No lighting, fog on, fog color */
481 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
482 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
483 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
484 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
485 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
486 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
488 /* First test: Both table fog and vertex fog off */
489 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
490 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
491 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
492 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
494 /* Start = 0, end = 1. Should be default, but set them */
495 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
496 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
497 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
498 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
500 if(IDirect3DDevice8_BeginScene(device) == D3D_OK)
502 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
503 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
504 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
505 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
506 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
507 sizeof(untransformed_1[0]));
508 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
510 /* That makes it use the Z value */
511 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
512 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
513 /* Untransformed, vertex fog != none (or table fog != none):
514 * Use the Z value as input into the equation
516 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
517 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
518 sizeof(untransformed_2[0]));
519 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
521 /* transformed verts */
522 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
523 ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
524 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
525 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
526 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
527 sizeof(transformed_1[0]));
528 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
530 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
531 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
532 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
535 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
536 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
537 sizeof(transformed_2[0]));
538 ok(SUCCEEDED(hr), "IDirect3DDevice8_DrawIndexedPrimitiveUP returned %#x.\n", hr);
540 hr = IDirect3DDevice8_EndScene(device);
541 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
545 ok(FALSE, "BeginScene failed\n");
548 color = getPixelColor(device, 160, 360);
549 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
550 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
551 color = getPixelColor(device, 160, 120);
552 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
553 "Untransformed vertex with linear vertex fog has color %08x\n", color);
554 color = getPixelColor(device, 480, 120);
555 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
556 "Transformed vertex with linear vertex fog has color %08x\n", color);
557 color = getPixelColor(device, 480, 360);
558 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
559 "Transformed vertex with linear table fog has color %08x\n", color);
561 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
563 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
565 /* A simple fog + non-identity world matrix test */
566 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat1);
567 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
569 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
570 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
571 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
572 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
574 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
575 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
577 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
579 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
580 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
582 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
583 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
584 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
586 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
587 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
588 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
590 hr = IDirect3DDevice8_EndScene(device);
591 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
595 ok(FALSE, "BeginScene failed\n");
598 color = getPixelColor(device, 160, 360);
599 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
600 color = getPixelColor(device, 160, 120);
601 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
602 "Fogged out quad has color %08x\n", color);
604 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
606 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
607 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat2);
608 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
609 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) proj_mat);
610 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
612 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
613 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
615 if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
617 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
618 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
620 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
621 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
622 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
624 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
625 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
626 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
628 hr = IDirect3DDevice8_EndScene(device);
629 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
633 ok(FALSE, "BeginScene failed\n");
636 color = getPixelColor(device, 160, 360);
637 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
638 color = getPixelColor(device, 160, 120);
639 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
640 "Fogged out quad has color %08x\n", color);
642 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
644 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) ident_mat);
645 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
646 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) ident_mat);
647 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
651 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
654 /* Turn off the fog master switch to avoid confusing other tests */
655 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
656 ok(hr == D3D_OK, "Turning off fog calculations returned %#08x\n", hr);
659 /* This tests fog in combination with shaders.
660 * What's tested: linear fog (vertex and table) with pixel shader
661 * linear table fog with non foggy vertex shader
662 * vertex fog with foggy vertex shader, non-linear
663 * fog with shader, non-linear fog with foggy shader,
664 * linear table fog with foggy shader */
665 static void fog_with_shader_test(IDirect3DDevice8 *device)
676 /* Basic vertex shader without fog computation ("non foggy") */
677 static const DWORD vertex_shader_code1[] =
679 0xfffe0100, /* vs.1.0 */
680 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
681 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
684 /* Basic vertex shader with reversed fog computation ("foggy") */
685 static const DWORD vertex_shader_code2[] =
687 0xfffe0100, /* vs.1.0 */
688 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
689 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
690 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
691 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
694 /* Basic pixel shader */
695 static const DWORD pixel_shader_code[] =
697 0xffff0101, /* ps_1_1 */
698 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
701 static struct vertex quad[] =
703 {-1.0f, -1.0f, 0.0f, 0xffff0000},
704 {-1.0f, 1.0f, 0.0f, 0xffff0000},
705 { 1.0f, -1.0f, 0.0f, 0xffff0000},
706 { 1.0f, 1.0f, 0.0f, 0xffff0000},
708 static const DWORD decl[] =
711 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
712 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
715 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
716 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
717 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
718 DWORD pixel_shader[2] = {0, 0};
720 /* This reference data was collected on a nVidia GeForce 7600GS
721 * driver version 84.19 DirectX version 9.0c on Windows XP */
722 static const struct test_data_t
728 unsigned int color[11];
732 /* Only pixel shader */
733 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
734 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
735 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
736 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
737 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
738 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
739 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
740 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
741 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
742 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
743 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
744 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
745 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
746 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
747 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
750 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
751 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
752 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
753 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
754 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
755 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
756 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
757 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
758 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
760 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
761 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
762 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
763 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
764 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
765 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
767 /* Vertex shader and pixel shader */
768 /* The next 4 tests would read the fog coord output, but it isn't available.
769 * The result is a fully fogged quad, no matter what the Z coord is. */
770 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
771 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
772 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
773 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
774 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
775 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
776 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
777 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
778 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
779 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
780 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
781 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
783 /* These use the Z coordinate with linear table fog */
784 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
785 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
786 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
787 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
788 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
789 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
790 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
791 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
792 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
793 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
794 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
795 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
797 /* Non-linear table fog without fog coord */
798 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
799 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
800 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
801 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
802 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
803 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
805 /* These tests fail on older Nvidia drivers */
806 /* Foggy vertex shader */
807 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
808 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
809 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
810 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
811 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
812 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
813 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
814 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
815 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
816 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
817 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
818 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
820 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
821 * all using the fixed fog-coord linear fog */
822 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
823 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
824 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
825 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
826 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
827 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
828 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
829 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
830 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
831 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
832 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
833 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
835 /* These use table fog. Here the shader-provided fog coordinate is
836 * ignored and the z coordinate used instead */
837 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
838 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
839 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
840 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
841 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
842 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
843 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
844 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
845 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
848 /* NOTE: changing these values will not affect the tests with foggy vertex shader,
849 * as the values are hardcoded in the shader constant */
853 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
854 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
855 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
856 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
857 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
858 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
860 /* Set shader constant value */
861 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
862 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
863 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
864 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
866 /* Setup initial states: No lighting, fog on, fog color */
867 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
868 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
869 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
870 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
871 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
872 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
874 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
875 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
876 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
877 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
879 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
880 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
881 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
882 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
883 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
885 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
887 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
888 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
889 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
890 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
891 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
892 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
893 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
894 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
896 for(j = 0; j < 11; ++j)
898 /* Don't use the whole zrange to prevent rounding errors */
899 quad[0].z = 0.001f + j / 10.02f;
900 quad[1].z = 0.001f + j / 10.02f;
901 quad[2].z = 0.001f + j / 10.02f;
902 quad[3].z = 0.001f + j / 10.02f;
904 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0f, 0);
905 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
907 hr = IDirect3DDevice8_BeginScene(device);
908 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
910 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
911 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
913 hr = IDirect3DDevice8_EndScene(device);
914 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
916 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
917 color = getPixelColor(device, 128, 240);
918 ok(color_match(color, test_data[i].color[j], 13),
919 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
920 test_data[i].vshader, test_data[i].pshader,
921 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
923 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
928 hr = IDirect3DDevice8_SetVertexShader(device, 0);
929 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
930 hr = IDirect3DDevice8_SetPixelShader(device, 0);
931 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
932 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
933 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
935 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
936 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
937 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
940 static void present_test(IDirect3DDevice8 *device)
942 struct vertex quad[] =
944 {-1.0f, -1.0f, 0.9f, 0xffff0000},
945 {-1.0f, 1.0f, 0.9f, 0xffff0000},
946 { 1.0f, -1.0f, 0.1f, 0xffff0000},
947 { 1.0f, 1.0f, 0.1f, 0xffff0000},
952 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
953 * then call Present. Then clear the color buffer to make sure it has some defined content
954 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
955 * by the depth value.
957 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
958 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
959 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
960 ok(SUCCEEDED(hr), "IDirect3DDevice8_Present returned %#x.\n", hr);
961 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4f, 0);
962 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear returned %#x.\n", hr);
964 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
965 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
966 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
967 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
968 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
969 ok(hr == D3D_OK, "IDirect3DDevice8_SetFVF returned %08x\n", hr);
971 hr = IDirect3DDevice8_BeginScene(device);
972 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %08x\n", hr);
975 /* No lights are defined... That means, lit vertices should be entirely black */
976 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
977 ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %08x\n", hr);
979 hr = IDirect3DDevice8_EndScene(device);
980 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %08x\n", hr);
983 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
984 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
986 color = getPixelColor(device, 512, 240);
987 ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
988 color = getPixelColor(device, 64, 240);
989 ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
991 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
992 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
995 static void test_rcp_rsq(IDirect3DDevice8 *device)
1000 float constant[4] = {1.0, 1.0, 1.0, 2.0};
1002 static const float quad[][3] = {
1003 {-1.0f, -1.0f, 0.0f},
1004 {-1.0f, 1.0f, 0.0f},
1005 { 1.0f, -1.0f, 0.0f},
1006 { 1.0f, 1.0f, 0.0f},
1009 const DWORD rcp_test[] = {
1010 0xfffe0101, /* vs.1.1 */
1012 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1013 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
1014 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1015 0x00303030, /* enough to make windows happy */
1017 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1018 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
1019 0x0000ffff /* END */
1022 const DWORD rsq_test[] = {
1023 0xfffe0101, /* vs.1.1 */
1025 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
1026 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
1027 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
1028 0x00303030, /* enough to make windows happy */
1030 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1031 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
1032 0x0000ffff /* END */
1038 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* D3DVSDE_POSITION, Register v0 */
1042 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
1043 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1045 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
1046 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
1048 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1049 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1050 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
1052 hr = IDirect3DDevice8_BeginScene(device);
1053 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
1056 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1057 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
1058 hr = IDirect3DDevice8_EndScene(device);
1059 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
1062 color = getPixelColor(device, 320, 240);
1063 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), 4),
1064 "RCP test returned color 0x%08x, expected 0x00808080.\n", color);
1066 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1067 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
1069 IDirect3DDevice8_SetVertexShader(device, 0);
1070 IDirect3DDevice8_DeleteVertexShader(device, shader);
1072 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff996633, 0.0f, 0);
1073 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1075 hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
1076 ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
1078 hr = IDirect3DDevice8_SetVertexShader(device, shader);
1079 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1080 IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
1082 hr = IDirect3DDevice8_BeginScene(device);
1083 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
1086 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
1087 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
1088 hr = IDirect3DDevice8_EndScene(device);
1089 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
1092 color = getPixelColor(device, 320, 240);
1093 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), 4),
1094 "RSQ test returned color 0x%08x, expected 0x00b4b4b4.\n", color);
1096 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1097 ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
1099 IDirect3DDevice8_SetVertexShader(device, 0);
1100 IDirect3DDevice8_DeleteVertexShader(device, shader);
1103 static void offscreen_test(IDirect3DDevice8 *device)
1106 IDirect3DTexture8 *offscreenTexture = NULL;
1107 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
1110 static const float quad[][5] = {
1111 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1112 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1113 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1114 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1117 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
1118 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
1120 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1121 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
1123 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
1124 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1125 if(!offscreenTexture) {
1126 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1127 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
1128 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1129 if(!offscreenTexture) {
1130 skip("Cannot create an offscreen render target\n");
1135 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1136 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
1141 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1142 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
1147 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1148 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1150 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1151 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1152 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1153 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1154 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
1155 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
1156 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
1157 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
1158 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1159 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
1161 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
1162 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
1163 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
1164 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1165 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
1167 /* Draw without textures - Should result in a white quad */
1168 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1169 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1171 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1172 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
1173 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1174 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1176 /* This time with the texture */
1177 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1178 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1180 IDirect3DDevice8_EndScene(device);
1183 /* Center quad - should be white */
1184 color = getPixelColor(device, 320, 240);
1185 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1186 /* Some quad in the cleared part of the texture */
1187 color = getPixelColor(device, 170, 240);
1188 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1189 /* Part of the originally cleared back buffer */
1190 color = getPixelColor(device, 10, 10);
1191 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1193 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1194 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1195 * the offscreen rendering mode this test would succeed or fail
1197 color = getPixelColor(device, 10, 470);
1198 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1201 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1204 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1205 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetTexture returned %#x.\n", hr);
1207 /* restore things */
1209 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1210 ok(SUCCEEDED(hr), "IDirect3DDevice8_SetRenderTarget returned %#x.\n", hr);
1211 IDirect3DSurface8_Release(backbuffer);
1213 if(offscreenTexture) {
1214 IDirect3DTexture8_Release(offscreenTexture);
1217 IDirect3DSurface8_Release(offscreen);
1220 IDirect3DSurface8_Release(depthstencil);
1224 static void alpha_test(IDirect3DDevice8 *device)
1227 IDirect3DTexture8 *offscreenTexture;
1228 IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
1231 struct vertex quad1[] =
1233 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
1234 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
1235 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
1236 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
1238 struct vertex quad2[] =
1240 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
1241 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
1242 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
1243 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
1245 static const float composite_quad[][5] = {
1246 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
1247 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
1248 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
1249 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
1252 /* Clear the render target with alpha = 0.5 */
1253 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1254 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1256 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
1257 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
1259 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
1260 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
1262 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1263 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
1267 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1268 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
1273 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1274 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1276 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1277 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1278 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1279 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
1280 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
1281 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
1282 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
1283 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
1284 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1285 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
1287 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1288 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1289 if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
1291 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
1292 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1293 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1294 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1295 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1296 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1297 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1299 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1300 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1301 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1302 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1303 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1304 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1306 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
1307 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
1308 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
1309 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
1310 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1311 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1312 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1314 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1315 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1316 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1317 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1318 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1319 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1321 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1322 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1323 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1324 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1325 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1326 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1328 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1329 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1331 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1332 * Disable alpha blending for the final composition
1334 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1335 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1336 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1337 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1339 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1340 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1341 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
1342 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1343 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1344 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1346 hr = IDirect3DDevice8_EndScene(device);
1347 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1350 color = getPixelColor(device, 160, 360);
1351 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1352 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
1354 color = getPixelColor(device, 160, 120);
1355 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
1356 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
1358 color = getPixelColor(device, 480, 360);
1359 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1360 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
1362 color = getPixelColor(device, 480, 120);
1363 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1364 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
1366 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1369 /* restore things */
1371 IDirect3DSurface8_Release(backbuffer);
1373 if(offscreenTexture) {
1374 IDirect3DTexture8_Release(offscreenTexture);
1377 IDirect3DSurface8_Release(offscreen);
1380 IDirect3DSurface8_Release(depthstencil);
1384 static void p8_texture_test(IDirect3DDevice8 *device)
1386 IDirect3D8 *d3d = NULL;
1388 IDirect3DTexture8 *texture = NULL, *texture2 = NULL;
1390 unsigned char *data;
1391 DWORD color, red, green, blue;
1392 PALETTEENTRY table[256];
1396 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
1397 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
1398 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
1399 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
1402 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
1403 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
1404 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
1405 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
1408 IDirect3DDevice8_GetDirect3D(device, &d3d);
1410 if(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1411 D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK) {
1412 skip("D3DFMT_P8 textures not supported\n");
1416 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1417 D3DPOOL_MANAGED, &texture2);
1418 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1420 skip("Failed to create D3DFMT_P8 texture\n");
1424 memset(&lr, 0, sizeof(lr));
1425 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
1426 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1430 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
1431 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1433 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1434 D3DPOOL_MANAGED, &texture);
1435 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1437 skip("Failed to create D3DFMT_P8 texture\n");
1441 memset(&lr, 0, sizeof(lr));
1442 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
1443 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1447 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1448 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1450 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1451 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1453 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1454 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1456 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
1457 alpha of every entry is set to 1.0, which MS says is required when there's no
1458 D3DPTEXTURECAPS_ALPHAPALETTE capability */
1459 for (i = 0; i < 256; i++) {
1460 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1461 table[i].peFlags = 0xff;
1463 table[1].peRed = 0xff;
1464 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1465 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1468 table[1].peBlue = 0xff;
1469 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1470 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1472 hr = IDirect3DDevice8_BeginScene(device);
1473 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1475 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1476 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1477 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1478 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1480 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1481 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1483 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1484 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1486 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1487 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1488 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1489 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1491 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
1492 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1493 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1494 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1496 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1497 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1498 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1499 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1501 hr = IDirect3DDevice8_EndScene(device);
1502 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1505 color = getPixelColor(device, 32, 32);
1506 red = (color & 0x00ff0000) >> 16;
1507 green = (color & 0x0000ff00) >> 8;
1508 blue = (color & 0x000000ff) >> 0;
1509 ok(red == 0xff && blue == 0 && green == 0,
1510 "got color %08x, expected 0x00ff0000\n", color);
1512 color = getPixelColor(device, 32, 320);
1513 red = (color & 0x00ff0000) >> 16;
1514 green = (color & 0x0000ff00) >> 8;
1515 blue = (color & 0x000000ff) >> 0;
1516 ok(red == 0 && blue == 0xff && green == 0,
1517 "got color %08x, expected 0x000000ff\n", color);
1519 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1520 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1522 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1523 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1525 hr = IDirect3DDevice8_BeginScene(device);
1526 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1528 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1529 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1531 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1532 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1534 hr = IDirect3DDevice8_EndScene(device);
1535 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1539 color = getPixelColor(device, 32, 32);
1540 red = (color & 0x00ff0000) >> 16;
1541 green = (color & 0x0000ff00) >> 8;
1542 blue = (color & 0x000000ff) >> 0;
1543 ok(red == 0 && blue == 0xff && green == 0,
1544 "got color %08x, expected 0x000000ff\n", color);
1546 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1547 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1549 /* Test palettes with alpha */
1550 IDirect3DDevice8_GetDeviceCaps(device, &caps);
1551 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
1552 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
1554 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1555 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1557 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1558 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1560 for (i = 0; i < 256; i++) {
1561 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1562 table[i].peFlags = 0xff;
1564 table[1].peRed = 0xff;
1565 table[1].peFlags = 0x80;
1566 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1567 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1570 table[1].peBlue = 0xff;
1571 table[1].peFlags = 0x80;
1572 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1573 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1575 hr = IDirect3DDevice8_BeginScene(device);
1576 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1578 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1579 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1580 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1581 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1583 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1584 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1586 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1587 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1589 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1590 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1592 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1593 ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1595 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1596 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1598 hr = IDirect3DDevice8_EndScene(device);
1599 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1602 color = getPixelColor(device, 32, 32);
1603 red = (color & 0x00ff0000) >> 16;
1604 green = (color & 0x0000ff00) >> 8;
1605 blue = (color & 0x000000ff) >> 0;
1606 ok(red >= 0x7e && red <= 0x81 && blue == 0 && green == 0,
1607 "got color %08x, expected 0x00800000 or near\n", color);
1609 color = getPixelColor(device, 32, 320);
1610 red = (color & 0x00ff0000) >> 16;
1611 green = (color & 0x0000ff00) >> 8;
1612 blue = (color & 0x000000ff) >> 0;
1613 ok(red == 0 && blue >= 0x7e && blue <= 0x81 && green == 0,
1614 "got color %08x, expected 0x00000080 or near\n", color);
1616 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1617 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1620 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1621 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1622 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1623 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1626 if(texture) IDirect3DTexture8_Release(texture);
1627 if(texture2) IDirect3DTexture8_Release(texture2);
1628 IDirect3D8_Release(d3d);
1631 static void texop_test(IDirect3DDevice8 *device)
1633 IDirect3DTexture8 *texture = NULL;
1634 D3DLOCKED_RECT locked_rect;
1640 static const struct {
1645 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
1646 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
1647 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
1648 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
1651 static const struct {
1657 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1658 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
1659 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
1660 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
1661 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1662 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1664 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
1665 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1667 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1668 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1669 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1670 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
1671 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
1672 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1673 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1674 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
1675 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
1676 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1677 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
1678 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
1679 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
1680 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
1681 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
1684 memset(&caps, 0, sizeof(caps));
1685 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1686 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
1688 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
1689 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
1691 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
1692 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
1693 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
1694 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1695 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
1696 hr = IDirect3DTexture8_UnlockRect(texture, 0);
1697 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1698 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1699 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1701 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
1702 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1703 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1704 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1705 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
1706 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1708 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
1709 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1711 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1712 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1713 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
1714 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1715 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
1716 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1718 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1719 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1721 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1723 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
1725 skip("tex operation %s not supported\n", test_data[i].name);
1729 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
1730 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
1732 hr = IDirect3DDevice8_BeginScene(device);
1733 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
1735 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1736 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
1738 hr = IDirect3DDevice8_EndScene(device);
1739 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
1741 color = getPixelColor(device, 320, 240);
1742 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
1743 test_data[i].name, color, test_data[i].result);
1745 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1746 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
1748 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1749 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1752 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1753 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1754 if (texture) IDirect3DTexture8_Release(texture);
1757 /* This test tests depth clamping / clipping behaviour:
1758 * - With software vertex processing, depth values are clamped to the
1759 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
1760 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
1761 * same as regular vertices here.
1762 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
1763 * Normal vertices are always clipped. Pretransformed vertices are
1764 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
1765 * - The viewport's MinZ/MaxZ is irrelevant for this.
1767 static void depth_clamp_test(IDirect3DDevice8 *device)
1769 const struct tvertex quad1[] =
1771 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1772 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
1773 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1774 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
1776 const struct tvertex quad2[] =
1778 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1779 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1780 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1781 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1783 const struct tvertex quad3[] =
1785 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1786 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
1787 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1788 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
1790 const struct tvertex quad4[] =
1792 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1793 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
1794 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1795 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1797 const struct vertex quad5[] =
1799 { -0.5f, 0.5f, 10.0f, 0xff14f914},
1800 { 0.5f, 0.5f, 10.0f, 0xff14f914},
1801 { -0.5f, -0.5f, 10.0f, 0xff14f914},
1802 { 0.5f, -0.5f, 10.0f, 0xff14f914},
1804 const struct vertex quad6[] =
1806 { -1.0f, 0.5f, 10.0f, 0xfff91414},
1807 { 1.0f, 0.5f, 10.0f, 0xfff91414},
1808 { -1.0f, 0.25f, 10.0f, 0xfff91414},
1809 { 1.0f, 0.25f, 10.0f, 0xfff91414},
1824 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1825 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1827 hr = IDirect3DDevice8_SetViewport(device, &vp);
1828 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1830 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
1831 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1833 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1834 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1835 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1836 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1837 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1838 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1839 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1840 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1842 hr = IDirect3DDevice8_BeginScene(device);
1843 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1845 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1846 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
1848 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1849 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1850 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1851 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1853 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1854 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1856 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1857 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1858 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
1859 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1861 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1862 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1863 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1864 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1866 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
1867 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1869 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1870 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1872 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
1873 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1875 hr = IDirect3DDevice8_EndScene(device);
1876 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1878 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1880 color = getPixelColor(device, 75, 75);
1881 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1882 color = getPixelColor(device, 150, 150);
1883 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1884 color = getPixelColor(device, 320, 240);
1885 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1886 color = getPixelColor(device, 320, 330);
1887 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1888 color = getPixelColor(device, 320, 330);
1889 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1893 color = getPixelColor(device, 75, 75);
1894 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1895 color = getPixelColor(device, 150, 150);
1896 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1897 color = getPixelColor(device, 320, 240);
1898 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
1899 color = getPixelColor(device, 320, 330);
1900 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1901 color = getPixelColor(device, 320, 330);
1902 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1905 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1906 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1910 hr = IDirect3DDevice8_SetViewport(device, &vp);
1911 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1914 static void depth_buffer_test(IDirect3DDevice8 *device)
1916 static const struct vertex quad1[] =
1918 { -1.0, 1.0, 0.33f, 0xff00ff00},
1919 { 1.0, 1.0, 0.33f, 0xff00ff00},
1920 { -1.0, -1.0, 0.33f, 0xff00ff00},
1921 { 1.0, -1.0, 0.33f, 0xff00ff00},
1923 static const struct vertex quad2[] =
1925 { -1.0, 1.0, 0.50f, 0xffff00ff},
1926 { 1.0, 1.0, 0.50f, 0xffff00ff},
1927 { -1.0, -1.0, 0.50f, 0xffff00ff},
1928 { 1.0, -1.0, 0.50f, 0xffff00ff},
1930 static const struct vertex quad3[] =
1932 { -1.0, 1.0, 0.66f, 0xffff0000},
1933 { 1.0, 1.0, 0.66f, 0xffff0000},
1934 { -1.0, -1.0, 0.66f, 0xffff0000},
1935 { 1.0, -1.0, 0.66f, 0xffff0000},
1937 static const DWORD expected_colors[4][4] =
1939 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1940 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1941 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
1942 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
1945 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
1946 IDirect3DSurface8 *depth_stencil;
1959 hr = IDirect3DDevice8_SetViewport(device, &vp);
1960 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1962 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1963 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1964 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1966 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1967 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1968 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1969 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1970 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1971 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1973 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1974 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1975 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1976 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1977 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
1978 D3DMULTISAMPLE_NONE, FALSE, &rt1);
1979 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1980 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1981 D3DMULTISAMPLE_NONE, FALSE, &rt2);
1982 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1983 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1984 D3DMULTISAMPLE_NONE, FALSE, &rt3);
1985 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1987 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
1988 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1989 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
1990 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1992 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1993 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1994 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1995 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1997 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1998 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1999 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
2000 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2002 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
2003 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2004 hr = IDirect3DDevice8_BeginScene(device);
2005 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2006 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
2007 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2008 hr = IDirect3DDevice8_EndScene(device);
2009 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2011 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2012 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2014 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2015 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2017 hr = IDirect3DDevice8_BeginScene(device);
2018 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2019 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
2020 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2021 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
2022 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2023 hr = IDirect3DDevice8_EndScene(device);
2024 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2026 for (i = 0; i < 4; ++i)
2028 for (j = 0; j < 4; ++j)
2030 unsigned int x = 80 * ((2 * j) + 1);
2031 unsigned int y = 60 * ((2 * i) + 1);
2032 color = getPixelColor(device, x, y);
2033 ok(color_match(color, expected_colors[i][j], 0),
2034 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
2038 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2039 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2041 IDirect3DSurface8_Release(depth_stencil);
2042 IDirect3DSurface8_Release(backbuffer);
2043 IDirect3DSurface8_Release(rt3);
2044 IDirect3DSurface8_Release(rt2);
2045 IDirect3DSurface8_Release(rt1);
2048 /* Test that partial depth copies work the way they're supposed to. The clear
2049 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
2050 * the following draw should only copy back the part that was modified. */
2051 static void depth_buffer2_test(IDirect3DDevice8 *device)
2053 static const struct vertex quad[] =
2055 { -1.0, 1.0, 0.66f, 0xffff0000},
2056 { 1.0, 1.0, 0.66f, 0xffff0000},
2057 { -1.0, -1.0, 0.66f, 0xffff0000},
2058 { 1.0, -1.0, 0.66f, 0xffff0000},
2061 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
2062 IDirect3DSurface8 *depth_stencil;
2075 hr = IDirect3DDevice8_SetViewport(device, &vp);
2076 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2078 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2079 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2080 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2081 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2082 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2083 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2084 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2085 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2086 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2087 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2089 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2090 D3DMULTISAMPLE_NONE, FALSE, &rt1);
2091 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2092 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
2093 D3DMULTISAMPLE_NONE, FALSE, &rt2);
2094 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2095 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
2096 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2097 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
2098 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2100 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
2101 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2102 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2103 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2105 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2106 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2107 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
2108 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2110 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
2111 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2112 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
2113 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2115 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
2116 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2118 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2119 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2121 hr = IDirect3DDevice8_BeginScene(device);
2122 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2123 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2124 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2125 hr = IDirect3DDevice8_EndScene(device);
2126 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2128 for (i = 0; i < 4; ++i)
2130 for (j = 0; j < 4; ++j)
2132 unsigned int x = 80 * ((2 * j) + 1);
2133 unsigned int y = 60 * ((2 * i) + 1);
2134 color = getPixelColor(device, x, y);
2135 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
2136 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
2140 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2141 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2143 IDirect3DSurface8_Release(depth_stencil);
2144 IDirect3DSurface8_Release(backbuffer);
2145 IDirect3DSurface8_Release(rt2);
2146 IDirect3DSurface8_Release(rt1);
2149 static void intz_test(IDirect3DDevice8 *device)
2151 static const DWORD ps_code[] =
2153 0xffff0101, /* ps_1_1 */
2154 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2155 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2156 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2157 0x00000042, 0xb00f0000, /* tex t0 */
2158 0x00000042, 0xb00f0001, /* tex t1 */
2159 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2160 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2161 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2162 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2163 0x0000ffff, /* end */
2169 float s1, t1, p1, q1;
2173 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2174 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2175 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2176 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2180 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2181 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2182 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2183 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2187 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2188 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2189 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2190 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2199 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2200 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2201 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2202 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2203 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2204 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2205 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2206 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2209 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2210 IDirect3DTexture8 *texture;
2211 IDirect3DSurface8 *ds;
2218 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2219 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2220 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2222 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
2225 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2227 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2231 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2232 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2234 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2235 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2238 skip("No INTZ support, skipping INTZ test.\n");
2242 IDirect3D8_Release(d3d8);
2244 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2245 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2246 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2247 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2249 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2250 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2251 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2252 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2253 D3DMULTISAMPLE_NONE, FALSE, &rt);
2254 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2255 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2256 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2258 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2259 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2260 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2261 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2262 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2263 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2264 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2265 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2266 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2268 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2270 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2271 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2272 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2273 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2274 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2275 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2276 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2277 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2279 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2280 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2281 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2282 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2283 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2284 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2285 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2286 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2287 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2288 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2289 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2290 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2291 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2293 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2294 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2296 /* Render offscreen, using the INTZ texture as depth buffer */
2297 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2298 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2299 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2300 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2302 /* Setup the depth/stencil surface. */
2303 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2304 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2306 hr = IDirect3DDevice8_BeginScene(device);
2307 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2308 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2309 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2310 hr = IDirect3DDevice8_EndScene(device);
2311 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2313 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2314 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2315 IDirect3DSurface8_Release(ds);
2316 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2317 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2318 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2319 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2320 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2321 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2323 /* Read the depth values back. */
2324 hr = IDirect3DDevice8_BeginScene(device);
2325 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2326 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2327 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2328 hr = IDirect3DDevice8_EndScene(device);
2329 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2331 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2333 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2334 ok(color_match(color, expected_colors[i].color, 1),
2335 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2336 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2339 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2340 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2342 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2343 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2344 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2345 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2346 IDirect3DTexture8_Release(texture);
2348 /* Render onscreen while using the INTZ texture as depth buffer */
2349 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2350 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2351 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2352 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2353 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2354 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2355 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2356 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2357 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2359 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2360 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2362 hr = IDirect3DDevice8_BeginScene(device);
2363 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2364 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2365 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2366 hr = IDirect3DDevice8_EndScene(device);
2367 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2369 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2370 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2371 IDirect3DSurface8_Release(ds);
2372 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2373 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2374 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2375 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2376 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2377 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2379 /* Read the depth values back. */
2380 hr = IDirect3DDevice8_BeginScene(device);
2381 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2382 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2383 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2384 hr = IDirect3DDevice8_EndScene(device);
2385 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2387 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2389 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2390 ok(color_match(color, expected_colors[i].color, 1),
2391 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2392 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2395 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2396 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2398 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2399 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2400 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2401 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2402 IDirect3DTexture8_Release(texture);
2404 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
2405 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2406 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2407 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2408 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2409 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2410 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2411 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2412 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2413 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2415 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2416 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2418 hr = IDirect3DDevice8_BeginScene(device);
2419 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2420 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
2421 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2422 hr = IDirect3DDevice8_EndScene(device);
2423 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2425 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2426 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2428 hr = IDirect3DDevice8_BeginScene(device);
2429 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2430 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
2431 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2432 hr = IDirect3DDevice8_EndScene(device);
2433 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2435 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2436 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2437 IDirect3DSurface8_Release(ds);
2438 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2439 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2440 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2441 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2442 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2443 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2445 /* Read the depth values back. */
2446 hr = IDirect3DDevice8_BeginScene(device);
2447 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2448 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2449 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2450 hr = IDirect3DDevice8_EndScene(device);
2451 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2453 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2455 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2456 ok(color_match(color, expected_colors[i].color, 1),
2457 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2458 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2461 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2462 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2464 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2465 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2466 IDirect3DSurface8_Release(original_ds);
2467 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2468 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2469 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2470 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2471 IDirect3DTexture8_Release(texture);
2472 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2473 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2474 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2475 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2477 IDirect3DSurface8_Release(original_rt);
2478 IDirect3DSurface8_Release(rt);
2481 static void shadow_test(IDirect3DDevice8 *device)
2483 static const DWORD ps_code[] =
2485 0xffff0101, /* ps_1_1 */
2486 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2487 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2488 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2489 0x00000042, 0xb00f0000, /* tex t0 */
2490 0x00000042, 0xb00f0001, /* tex t1 */
2491 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2492 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2493 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2494 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2495 0x0000ffff, /* end */
2504 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
2505 {D3DFMT_D32, "D3DFMT_D32"},
2506 {D3DFMT_D15S1, "D3DFMT_D15S1"},
2507 {D3DFMT_D24S8, "D3DFMT_D24S8"},
2508 {D3DFMT_D24X8, "D3DFMT_D24X8"},
2509 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
2510 {D3DFMT_D16, "D3DFMT_D16"},
2516 float s1, t1, p1, q1;
2520 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2521 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2522 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2523 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2532 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2533 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2534 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2535 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2536 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2537 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2538 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2539 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2542 IDirect3DSurface8 *original_ds, *original_rt, *rt;
2549 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2550 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2551 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2553 skip("No pixel shader 1.1 support, skipping shadow test.\n");
2557 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2558 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2559 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2560 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2561 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2562 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2564 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2565 D3DMULTISAMPLE_NONE, FALSE, &rt);
2566 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2567 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2568 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2570 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2571 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2572 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2573 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2574 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2575 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2576 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2577 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2578 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2579 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2580 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2582 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2583 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2584 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2585 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2586 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2587 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2588 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2589 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2591 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2592 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2593 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2594 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2595 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2596 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2597 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2598 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2599 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2600 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2601 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2602 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2603 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2605 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2607 D3DFORMAT format = formats[i].format;
2608 IDirect3DTexture8 *texture;
2609 IDirect3DSurface8 *ds;
2612 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2613 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2614 if (FAILED(hr)) continue;
2616 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2617 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2618 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2620 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2621 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2623 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2624 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2626 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2627 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2629 /* Setup the depth/stencil surface. */
2630 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2631 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2633 hr = IDirect3DDevice8_BeginScene(device);
2634 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2635 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2636 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2637 hr = IDirect3DDevice8_EndScene(device);
2638 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2640 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2641 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2642 IDirect3DSurface8_Release(ds);
2644 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2645 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2646 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2647 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2649 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2650 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2652 /* Do the actual shadow mapping. */
2653 hr = IDirect3DDevice8_BeginScene(device);
2654 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2655 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2656 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2657 hr = IDirect3DDevice8_EndScene(device);
2658 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2660 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2661 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2662 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2663 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2664 IDirect3DTexture8_Release(texture);
2666 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2668 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2669 ok(color_match(color, expected_colors[j].color, 0),
2670 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2671 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2672 formats[i].name, color);
2675 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2676 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2679 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2680 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2681 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2682 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2684 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2685 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2686 IDirect3DSurface8_Release(original_ds);
2688 IDirect3DSurface8_Release(original_rt);
2689 IDirect3DSurface8_Release(rt);
2691 IDirect3D8_Release(d3d8);
2694 static void multisample_copy_rects_test(IDirect3DDevice8 *device)
2696 IDirect3DSurface8 *original_ds, *original_rt, *ds, *ds_plain, *rt, *readback;
2697 RECT src_rect = {64, 64, 128, 128};
2698 POINT dst_point = {96, 96};
2699 D3DLOCKED_RECT locked_rect;
2704 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2705 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2706 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2707 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2708 IDirect3D8_Release(d3d8);
2711 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
2715 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
2716 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2717 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2718 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2719 D3DMULTISAMPLE_2_SAMPLES, &ds);
2720 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2721 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2722 D3DMULTISAMPLE_NONE, &ds_plain);
2723 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2724 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
2725 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
2727 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2728 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2729 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2730 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2732 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2733 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2735 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2736 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2738 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
2739 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2741 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
2742 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2744 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2745 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2747 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
2748 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2750 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
2751 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
2753 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
2754 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2756 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
2757 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
2759 hr = IDirect3DSurface8_UnlockRect(readback);
2760 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
2762 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2763 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
2765 IDirect3DSurface8_Release(original_ds);
2766 IDirect3DSurface8_Release(original_rt);
2767 IDirect3DSurface8_Release(readback);
2768 IDirect3DSurface8_Release(ds_plain);
2769 IDirect3DSurface8_Release(ds);
2770 IDirect3DSurface8_Release(rt);
2773 static void resz_test(IDirect3DDevice8 *device)
2775 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
2780 static const DWORD ps_code[] =
2782 0xffff0101, /* ps_1_1 */
2783 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
2784 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
2785 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
2786 0x00000042, 0xb00f0000, /* tex t0 */
2787 0x00000042, 0xb00f0001, /* tex t1 */
2788 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
2789 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
2790 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
2791 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
2792 0x0000ffff, /* end */
2798 float s1, t1, p1, q1;
2802 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2803 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2804 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2805 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2814 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2815 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2816 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2817 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2818 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2819 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2820 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2821 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2823 IDirect3DTexture8 *texture;
2826 hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2827 ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2828 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2829 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2832 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
2835 hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2836 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2839 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
2842 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2843 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2846 skip("No INTZ support, skipping RESZ test.\n");
2849 hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2850 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
2853 skip("No RESZ support, skipping RESZ test.\n");
2856 IDirect3D8_Release(d3d8);
2858 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2859 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2860 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2862 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2866 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2867 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2868 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2869 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2871 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2872 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2873 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2874 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2875 D3DMULTISAMPLE_2_SAMPLES, &ds);
2877 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2878 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2879 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2880 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
2881 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2883 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
2884 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2885 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
2886 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2888 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2889 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2890 IDirect3DSurface8_Release(intz_ds);
2891 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2892 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2894 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2895 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2896 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2897 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2898 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2899 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2900 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2901 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2902 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2903 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2904 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2907 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2908 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2909 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2910 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2911 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2912 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2913 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2915 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2916 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2917 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2918 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2919 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2920 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2921 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2922 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2923 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2924 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2925 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2926 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2927 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2929 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
2930 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2931 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2933 hr = IDirect3DDevice8_BeginScene(device);
2934 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2935 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2936 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2938 /* The destination depth texture has to be bound to sampler 0 */
2939 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2940 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2942 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
2943 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2944 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2945 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2946 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2947 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2948 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2949 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2950 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2951 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2952 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2954 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2955 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2956 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2958 /* The actual multisampled depth buffer resolve happens here */
2959 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2960 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2961 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
2962 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
2964 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2965 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2966 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2967 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2968 hr = IDirect3DDevice8_SetPixelShader(device, ps);
2969 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2971 /* Read the depth values back. */
2972 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2973 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2974 hr = IDirect3DDevice8_EndScene(device);
2975 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2977 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2979 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2980 ok(color_match(color, expected_colors[i].color, 1),
2981 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2982 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2985 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2986 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2988 /* Test edge cases - try with no texture at all */
2989 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2990 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2991 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2992 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2993 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2994 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2996 hr = IDirect3DDevice8_BeginScene(device);
2997 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2998 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3000 hr = IDirect3DDevice8_EndScene(device);
3001 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3003 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3004 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3006 /* With a non-multisampled depth buffer */
3007 IDirect3DSurface8_Release(ds);
3008 IDirect3DSurface8_Release(rt);
3009 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
3010 D3DMULTISAMPLE_NONE, &ds);
3012 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3013 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3014 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3015 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3017 hr = IDirect3DDevice8_BeginScene(device);
3018 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3019 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3020 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3021 hr = IDirect3DDevice8_EndScene(device);
3022 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3024 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3025 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3027 hr = IDirect3DDevice8_BeginScene(device);
3028 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3029 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3030 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3031 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3032 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3033 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
3034 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3035 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3036 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3037 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
3038 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3039 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3040 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3041 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
3042 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3043 hr = IDirect3DDevice8_EndScene(device);
3044 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3046 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
3047 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
3049 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3050 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3051 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3052 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3054 /* Read the depth values back. */
3055 hr = IDirect3DDevice8_BeginScene(device);
3056 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3057 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3058 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3059 hr = IDirect3DDevice8_EndScene(device);
3060 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3062 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3064 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3065 ok(color_match(color, expected_colors[i].color, 1),
3066 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3067 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3070 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3071 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3073 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
3074 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3075 IDirect3DSurface8_Release(ds);
3076 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3077 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3078 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3079 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3080 IDirect3DTexture8_Release(texture);
3081 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3082 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3083 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3084 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3085 IDirect3DSurface8_Release(original_ds);
3086 IDirect3DSurface8_Release(original_rt);
3089 static void zenable_test(IDirect3DDevice8 *device)
3093 struct vec4 position;
3098 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
3099 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
3100 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
3101 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
3109 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3110 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
3111 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3112 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3114 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3115 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3116 hr = IDirect3DDevice8_BeginScene(device);
3117 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3118 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
3119 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3120 hr = IDirect3DDevice8_EndScene(device);
3121 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3123 for (i = 0; i < 4; ++i)
3125 for (j = 0; j < 4; ++j)
3127 x = 80 * ((2 * j) + 1);
3128 y = 60 * ((2 * i) + 1);
3129 color = getPixelColor(device, x, y);
3130 ok(color_match(color, 0x0000ff00, 1),
3131 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
3135 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3136 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3138 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3139 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3141 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
3142 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3144 static const DWORD vs_code[] =
3146 0xfffe0101, /* vs_1_1 */
3147 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3148 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
3151 static const DWORD ps_code[] =
3153 0xffff0101, /* ps_1_1 */
3154 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
3155 0x0000ffff /* end */
3157 static const struct vec3 quad[] =
3159 {-1.0f, -1.0f, -0.5f},
3160 {-1.0f, 1.0f, -0.5f},
3161 { 1.0f, -1.0f, 1.5f},
3162 { 1.0f, 1.0f, 1.5f},
3164 static const D3DCOLOR expected[] =
3166 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
3167 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
3168 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
3169 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
3171 static const DWORD decl[] =
3174 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
3179 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
3180 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3181 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3182 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
3183 hr = IDirect3DDevice8_SetVertexShader(device, vs);
3184 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3185 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3186 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3188 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
3189 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
3190 hr = IDirect3DDevice8_BeginScene(device);
3191 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3192 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3193 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3194 hr = IDirect3DDevice8_EndScene(device);
3195 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3197 for (i = 0; i < 4; ++i)
3199 for (j = 0; j < 4; ++j)
3201 x = 80 * ((2 * j) + 1);
3202 y = 60 * ((2 * i) + 1);
3203 color = getPixelColor(device, x, y);
3204 ok(color_match(color, expected[i * 4 + j], 1),
3205 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
3209 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3210 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
3212 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3213 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
3214 hr = IDirect3DDevice8_SetVertexShader(device, 0);
3215 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3216 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3217 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
3218 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
3219 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
3225 IDirect3DDevice8 *device_ptr;
3230 d3d8_handle = LoadLibraryA("d3d8.dll");
3233 win_skip("Could not load d3d8.dll\n");
3237 device_ptr = init_d3d8();
3240 win_skip("Could not initialize direct3d\n");
3244 IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
3246 /* Check for the reliability of the returned data */
3247 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3250 skip("Clear failed, can't assure correctness of the test results\n");
3254 color = getPixelColor(device_ptr, 1, 1);
3255 if(color !=0x00ff0000)
3257 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3260 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3262 hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3265 skip("Clear failed, can't assure correctness of the test results\n");
3269 color = getPixelColor(device_ptr, 639, 479);
3270 if(color != 0x0000ddee)
3272 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
3275 IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
3277 /* Now run the real test */
3278 depth_clamp_test(device_ptr);
3279 lighting_test(device_ptr);
3280 clear_test(device_ptr);
3281 fog_test(device_ptr);
3282 present_test(device_ptr);
3283 offscreen_test(device_ptr);
3284 alpha_test(device_ptr);
3286 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3288 test_rcp_rsq(device_ptr);
3289 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
3290 fog_with_shader_test(device_ptr);
3294 skip("No vs.1.1 support\n");
3297 p8_texture_test(device_ptr);
3298 texop_test(device_ptr);
3299 depth_buffer_test(device_ptr);
3300 depth_buffer2_test(device_ptr);
3301 intz_test(device_ptr);
3302 shadow_test(device_ptr);
3303 multisample_copy_rects_test(device_ptr);
3304 zenable_test(device_ptr);
3305 resz_test(device_ptr);
3309 D3DDEVICE_CREATION_PARAMETERS creation_parameters;
3312 IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
3313 DestroyWindow(creation_parameters.hFocusWindow);
3314 refcount = IDirect3DDevice8_Release(device_ptr);
3315 ok(!refcount, "Device has %u references left\n", refcount);