2 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
3 * Copyright (C) 2008 Alexander Dorofeyev
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 */
22 #include "wine/test.h"
27 static IDirectDraw7 *DirectDraw;
28 static IDirectDrawSurface7 *Surface;
29 static IDirectDrawSurface7 *depth_buffer;
30 static IDirect3D7 *Direct3D;
31 static IDirect3DDevice7 *Direct3DDevice;
33 static IDirectDraw *DirectDraw1;
34 static IDirectDrawSurface *Surface1;
35 static IDirect3D *Direct3D1;
36 static IDirect3DDevice *Direct3DDevice1;
37 static IDirect3DExecuteBuffer *ExecuteBuffer;
38 static IDirect3DViewport *Viewport;
40 static BOOL refdevice = FALSE;
42 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
44 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
46 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
48 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 static HRESULT WINAPI enum_z_fmt(DDPIXELFORMAT *fmt, void *ctx)
58 DDPIXELFORMAT *zfmt = ctx;
60 if(U1(*fmt).dwZBufferBitDepth > U1(*zfmt).dwZBufferBitDepth)
67 static BOOL createObjects(void)
70 HMODULE hmod = GetModuleHandleA("ddraw.dll");
75 if(!hmod) return FALSE;
76 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
77 if(!pDirectDrawCreateEx) return FALSE;
79 hr = pDirectDrawCreateEx(NULL, (void **) &DirectDraw, &IID_IDirectDraw7, NULL);
80 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
81 if(!DirectDraw) goto err;
83 wc.lpfnWndProc = DefWindowProc;
84 wc.lpszClassName = "d3d7_test_wc";
86 window = CreateWindow("d3d7_test_wc", "d3d7_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
88 hr = IDirectDraw7_SetCooperativeLevel(DirectDraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
89 ok(hr == DD_OK, "IDirectDraw7_SetCooperativeLevel failed with %08x\n", hr);
90 if(FAILED(hr)) goto err;
91 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 32, 0, 0);
93 /* 24 bit is fine too */
94 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 24, 0, 0);
97 ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "IDirectDraw7_SetDisplayMode failed with %08x\n", hr);
99 /* use trace, the caller calls skip() */
100 trace("SetDisplayMode failed\n");
104 hr = IDirectDraw7_QueryInterface(DirectDraw, &IID_IDirect3D7, (void**) &Direct3D);
105 if (hr == E_NOINTERFACE) goto err;
106 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
108 /* DirectDraw Flipping behavior doesn't seem that well-defined. The reference rasterizer behaves differently
109 * than hardware implementations. Request single buffering, that seems to work everywhere
111 memset(&ddsd, 0, sizeof(ddsd));
112 ddsd.dwSize = sizeof(ddsd);
113 ddsd.dwFlags = DDSD_CAPS;
114 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
115 ddsd.dwBackBufferCount = 1;
116 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &Surface, NULL);
117 if(FAILED(hr)) goto err;
119 memset(&zfmt, 0, sizeof(zfmt));
120 hr = IDirect3D7_EnumZBufferFormats(Direct3D, &IID_IDirect3DTnLHalDevice, enum_z_fmt, &zfmt);
121 if (FAILED(hr)) goto err;
122 if (zfmt.dwSize == 0) goto err;
124 memset(&ddsd, 0, sizeof(ddsd));
125 ddsd.dwSize = sizeof(ddsd);
126 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
127 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
128 U4(ddsd).ddpfPixelFormat = zfmt;
131 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &depth_buffer, NULL);
132 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr);
133 if (FAILED(hr)) goto err;
135 hr = IDirectDrawSurface_AddAttachedSurface(Surface, depth_buffer);
136 ok(SUCCEEDED(hr), "AddAttachedSurface failed, hr %#x.\n", hr);
137 if (FAILED(hr)) goto err;
139 hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DTnLHalDevice, Surface, &Direct3DDevice);
140 if (FAILED(hr) || !Direct3DDevice) goto err;
144 if(DirectDraw) IDirectDraw7_Release(DirectDraw);
145 if (depth_buffer) IDirectDrawSurface7_Release(depth_buffer);
146 if(Surface) IDirectDrawSurface7_Release(Surface);
147 if(Direct3D) IDirect3D7_Release(Direct3D);
148 if(Direct3DDevice) IDirect3DDevice7_Release(Direct3DDevice);
149 if(window) DestroyWindow(window);
153 static void releaseObjects(void)
155 IDirect3DDevice7_Release(Direct3DDevice);
156 IDirect3D7_Release(Direct3D);
157 IDirectDrawSurface7_Release(depth_buffer);
158 IDirectDrawSurface7_Release(Surface);
159 IDirectDraw7_Release(DirectDraw);
160 DestroyWindow(window);
163 static DWORD getPixelColor(IDirect3DDevice7 *device, UINT x, UINT y)
168 RECT rectToLock = {x, y, x+1, y+1};
169 IDirectDrawSurface7 *surf = NULL;
171 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
172 * to an offscreen surface and lock it instead of the front buffer
174 memset(&ddsd, 0, sizeof(ddsd));
175 ddsd.dwSize = sizeof(ddsd);
176 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
177 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
180 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
181 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
182 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with %08x\n", hr);
185 trace("cannot create helper surface\n");
189 memset(&ddsd, 0, sizeof(ddsd));
190 ddsd.dwSize = sizeof(ddsd);
191 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
193 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
194 ok(hr == DD_OK, "IDirectDrawSurface7_BltFast returned %08x\n", hr);
197 trace("Cannot blit\n");
202 hr = IDirectDrawSurface7_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
205 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
210 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
211 * really important for these tests
213 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
214 hr = IDirectDrawSurface7_Unlock(surf, NULL);
217 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
221 IDirectDrawSurface7_Release(surf);
225 static void set_viewport_size(IDirect3DDevice7 *device)
227 D3DVIEWPORT7 vp = {0};
230 IDirectDrawSurface7 *target;
232 hr = IDirect3DDevice7_GetRenderTarget(device, &target);
233 ok(hr == D3D_OK, "IDirect3DDevice7_GetRenderTarget returned %08x\n", hr);
235 memset(&ddsd, 0, sizeof(ddsd));
236 ddsd.dwSize = sizeof(ddsd);
237 IDirectDrawSurface7_GetSurfaceDesc(target, &ddsd);
238 ok(hr == D3D_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
239 IDirectDrawSurface7_Release(target);
241 vp.dwWidth = ddsd.dwWidth;
242 vp.dwHeight = ddsd.dwHeight;
243 hr = IDirect3DDevice7_SetViewport(device, &vp);
244 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport returned %08x\n", hr);
267 static void lighting_test(IDirect3DDevice7 *device)
270 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
271 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
274 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
275 0.0f, 1.0f, 0.0f, 0.0f,
276 0.0f, 0.0f, 1.0f, 0.0f,
277 0.0f, 0.0f, 0.0f, 1.0f };
279 struct vertex unlitquad[] =
281 {-1.0f, -1.0f, 0.1f, 0xffff0000},
282 {-1.0f, 0.0f, 0.1f, 0xffff0000},
283 { 0.0f, 0.0f, 0.1f, 0xffff0000},
284 { 0.0f, -1.0f, 0.1f, 0xffff0000},
286 struct vertex litquad[] =
288 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
289 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
290 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
291 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
293 struct nvertex unlitnquad[] =
295 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
296 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
297 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
298 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
300 struct nvertex litnquad[] =
302 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
303 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
304 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
305 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
307 WORD Indices[] = {0, 1, 2, 2, 3, 0};
309 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
310 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
312 /* Setup some states that may cause issues */
313 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
314 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
315 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
316 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
317 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
318 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
319 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
320 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
321 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
322 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
323 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
324 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
325 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_STENCILENABLE, FALSE);
326 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
327 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
328 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
329 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
330 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
331 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
332 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed with %08x\n", hr);
334 hr = IDirect3DDevice7_BeginScene(device);
335 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
338 /* No lights are defined... That means, lit vertices should be entirely black */
339 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
340 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
341 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, unlitquad, 4 /* NumVerts */,
342 Indices, 6 /* Indexcount */, 0 /* flags */);
343 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
346 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
347 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, litquad, 4 /* NumVerts */,
348 Indices, 6 /* Indexcount */, 0 /* flags */);
349 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
351 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
352 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
353 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, unlitnquad, 4 /* NumVerts */,
354 Indices, 6 /* Indexcount */, 0 /* flags */);
355 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
357 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
358 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
359 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, litnquad, 4 /* NumVerts */,
360 Indices, 6 /* Indexcount */, 0 /* flags */);
361 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
363 IDirect3DDevice7_EndScene(device);
364 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
367 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
368 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
369 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
370 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
371 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
372 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
373 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
374 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
376 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
377 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
380 static void clear_test(IDirect3DDevice7 *device)
382 /* Tests the correctness of clearing parameters */
388 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
389 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
391 /* Positive x, negative y */
393 U2(rect[0]).y1 = 480;
394 U3(rect[0]).x2 = 320;
395 U4(rect[0]).y2 = 240;
397 /* Positive x, positive y */
400 U3(rect[1]).x2 = 320;
401 U4(rect[1]).y2 = 240;
402 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
403 * is ignored, the positive is still cleared afterwards
405 hr = IDirect3DDevice7_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
406 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
408 /* negative x, negative y */
409 U1(rect_negneg).x1 = 640;
410 U2(rect_negneg).y1 = 240;
411 U3(rect_negneg).x2 = 320;
412 U4(rect_negneg).y2 = 0;
413 hr = IDirect3DDevice7_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
414 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
416 color = getPixelColor(device, 160, 360); /* lower left quad */
417 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
418 color = getPixelColor(device, 160, 120); /* upper left quad */
419 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
420 color = getPixelColor(device, 480, 360); /* lower right quad */
421 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
422 color = getPixelColor(device, 480, 120); /* upper right quad */
423 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
438 static void fog_test(IDirect3DDevice7 *device)
442 float start = 0.0, end = 1.0;
445 /* Gets full z based fog with linear fog, no fog with specular color */
446 struct sVertex untransformed_1[] = {
447 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
448 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
449 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
450 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
452 /* Ok, I am too lazy to deal with transform matrices */
453 struct sVertex untransformed_2[] = {
454 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
455 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
456 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
457 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
459 /* Untransformed ones. Give them a different diffuse color to make the test look
460 * nicer. It also makes making sure that they are drawn correctly easier.
462 struct sVertexT transformed_1[] = {
463 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
464 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
465 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
466 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
468 struct sVertexT transformed_2[] = {
469 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
470 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
471 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
472 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
474 WORD Indices[] = {0, 1, 2, 2, 3, 0};
476 float ident_mat[16] =
478 1.0f, 0.0f, 0.0f, 0.0f,
479 0.0f, 1.0f, 0.0f, 0.0f,
480 0.0f, 0.0f, 1.0f, 0.0f,
481 0.0f, 0.0f, 0.0f, 1.0f
483 float world_mat1[16] =
485 1.0f, 0.0f, 0.0f, 0.0f,
486 0.0f, 1.0f, 0.0f, 0.0f,
487 0.0f, 0.0f, 1.0f, 0.0f,
488 0.0f, 0.0f, -0.5f, 1.0f
490 float world_mat2[16] =
492 1.0f, 0.0f, 0.0f, 0.0f,
493 0.0f, 1.0f, 0.0f, 0.0f,
494 0.0f, 0.0f, 1.0f, 0.0f,
495 0.0f, 0.0f, 1.0f, 1.0f
499 1.0f, 0.0f, 0.0f, 0.0f,
500 0.0f, 1.0f, 0.0f, 0.0f,
501 0.0f, 0.0f, 1.0f, 0.0f,
502 0.0f, 0.0f, -1.0f, 1.0f
505 struct sVertex far_quad1[] =
507 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
508 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
509 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
510 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
512 struct sVertex far_quad2[] =
514 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
515 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
516 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
517 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
520 memset(&caps, 0, sizeof(caps));
521 hr = IDirect3DDevice7_GetCaps(device, &caps);
522 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
523 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
524 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr);
526 /* Setup initial states: No lighting, fog on, fog color */
527 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
528 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
529 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE);
530 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
531 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */);
532 ok(hr == D3D_OK, "Setting fog color returned %08x\n", hr);
534 /* First test: Both table fog and vertex fog off */
535 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
536 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
537 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
538 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
540 /* Start = 0, end = 1. Should be default, but set them */
541 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start));
542 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
543 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end));
544 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
546 if(IDirect3DDevice7_BeginScene(device) == D3D_OK)
548 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
549 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
550 untransformed_1, 4, Indices, 6, 0);
551 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
553 /* That makes it use the Z value */
554 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
555 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
556 /* Untransformed, vertex fog != none (or table fog != none):
557 * Use the Z value as input into the equation
559 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
560 untransformed_2, 4, Indices, 6, 0);
561 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
563 /* transformed verts */
564 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
565 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
566 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
567 transformed_1, 4, Indices, 6, 0);
568 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
570 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
571 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
572 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
575 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
576 transformed_2, 4, Indices, 6, 0);
577 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
579 hr = IDirect3DDevice7_EndScene(device);
580 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
584 ok(FALSE, "BeginScene failed\n");
587 color = getPixelColor(device, 160, 360);
588 ok(color_match(color, 0x00FF0000, 1), "Untransformed vertex with no table or vertex fog has color %08x\n", color);
589 color = getPixelColor(device, 160, 120);
590 ok(color_match(color, 0x0000FF00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
591 color = getPixelColor(device, 480, 120);
592 ok(color_match(color, 0x00FFFF00, 1), "Transformed vertex with linear vertex fog has color %08x\n", color);
593 if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
595 color = getPixelColor(device, 480, 360);
596 ok(color_match(color, 0x0000FF00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
600 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
601 * The settings above result in no fogging with vertex fog
603 color = getPixelColor(device, 480, 120);
604 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
605 trace("Info: Table fog not supported by this device\n");
608 if (caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
610 /* A simple fog + non-identity world matrix test */
611 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat1);
612 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %#08x\n", hr);
614 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
615 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
616 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
617 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
619 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
620 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %#08x\n", hr);
622 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
624 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
625 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad1, 4, Indices, 6, 0);
626 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
628 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
629 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad2, 4, Indices, 6, 0);
630 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
632 hr = IDirect3DDevice7_EndScene(device);
633 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
637 ok(FALSE, "BeginScene failed\n");
640 color = getPixelColor(device, 160, 360);
641 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
642 color = getPixelColor(device, 160, 120);
643 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
645 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
646 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat2);
647 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
648 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)proj_mat);
649 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
651 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
652 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
654 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
656 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
657 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_1, 4, Indices, 6, 0);
658 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
660 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
661 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_2, 4, Indices, 6, 0);
662 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
664 hr = IDirect3DDevice7_EndScene(device);
665 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
669 ok(FALSE, "BeginScene failed\n");
672 color = getPixelColor(device, 160, 360);
673 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
674 color = getPixelColor(device, 160, 120);
675 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
677 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)ident_mat);
678 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
679 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)ident_mat);
680 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
684 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
687 /* Turn off the fog master switch to avoid confusing other tests */
688 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
689 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
692 static void blt_test(IDirect3DDevice7 *device)
694 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
698 memset(&ddsd, 0, sizeof(ddsd));
699 ddsd.dwSize = sizeof(ddsd);
700 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
701 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
704 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
705 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
706 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
708 /* Offscreen blits with the same source as destination */
711 RECT src_rect, dst_rect;
713 /* Blit the whole surface to itself */
714 hr = IDirectDrawSurface_Blt(offscreen, NULL, offscreen, NULL, 0, NULL);
715 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
717 /* Overlapped blit */
718 dst_rect.left = 0; dst_rect.right = 480;
719 dst_rect.top = 0; dst_rect.bottom = 480;
720 src_rect.left = 160; src_rect.right = 640;
721 src_rect.top = 0; src_rect.bottom = 480;
722 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
723 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
725 /* Overlapped blit, flip-y through source rectangle (not allowed) */
726 dst_rect.left = 0; dst_rect.right = 480;
727 dst_rect.top = 0; dst_rect.bottom = 480;
728 src_rect.left = 160; src_rect.right = 640;
729 src_rect.top = 480; src_rect.bottom = 0;
730 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
731 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface7_Blt returned %08x\n", hr);
733 /* Overlapped blit, with shrinking in x */
734 dst_rect.left = 0; dst_rect.right = 480;
735 dst_rect.top = 0; dst_rect.bottom = 480;
736 src_rect.left = 160; src_rect.right = 480;
737 src_rect.top = 0; src_rect.bottom = 480;
738 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
739 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
742 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
743 ok(hr == D3D_OK, "Unable to obtain a surface pointer to the backbuffer, hr = %08x\n", hr);
745 /* backbuffer ==> texture blits */
746 if(SUCCEEDED(hr) && offscreen)
748 RECT src_rect, dst_rect;
750 /* backbuffer ==> texture, src_rect=NULL, dst_rect=NULL, no scaling */
751 hr = IDirectDrawSurface_Blt(offscreen, NULL, backbuffer, NULL, 0, NULL);
752 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
754 /* backbuffer ==> texture, full surface blits, no scaling */
755 dst_rect.left = 0; dst_rect.right = 640;
756 dst_rect.top = 0; dst_rect.bottom = 480;
757 src_rect.left = 0; src_rect.right = 640;
758 src_rect.top = 0; src_rect.bottom = 480;
759 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
760 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
762 /* backbuffer ==> texture, flip in y-direction through source rectangle, no scaling (allowed) */
763 dst_rect.left = 0; dst_rect.right = 640;
764 dst_rect.top = 480; dst_rect.top = 0;
765 src_rect.left = 0; src_rect.right = 640;
766 src_rect.top = 0; src_rect.bottom = 480;
767 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
768 ok(hr == DD_OK, "backbuffer => texture flip-y src_rect failed with hr = %08x\n", hr);
770 /* backbuffer ==> texture, flip in x-direction through source rectangle, no scaling (not allowed) */
771 dst_rect.left = 640; dst_rect.right = 0;
772 dst_rect.top = 0; dst_rect.top = 480;
773 src_rect.left = 0; src_rect.right = 640;
774 src_rect.top = 0; src_rect.bottom = 480;
775 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
776 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x src_rect failed with hr = %08x\n", hr);
778 /* backbuffer ==> texture, flip in y-direction through destination rectangle (not allowed) */
779 dst_rect.left = 0; dst_rect.right = 640;
780 dst_rect.top = 0; dst_rect.top = 480;
781 src_rect.left = 0; src_rect.right = 640;
782 src_rect.top = 480; src_rect.bottom = 0;
783 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
784 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-y dst_rect failed with hr = %08x\n", hr);
786 /* backbuffer ==> texture, flip in x-direction through destination rectangle, no scaling (not allowed) */
787 dst_rect.left = 0; dst_rect.right = 640;
788 dst_rect.top = 0; dst_rect.top = 480;
789 src_rect.left = 640; src_rect.right = 0;
790 src_rect.top = 0; src_rect.bottom = 480;
791 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
792 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x dst_rect failed with hr = %08x\n", hr);
795 if(offscreen) IDirectDrawSurface7_Release(offscreen);
796 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
799 static void offscreen_test(IDirect3DDevice7 *device)
802 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
806 static float quad[][5] = {
807 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
808 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
809 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
810 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
813 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
814 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
816 memset(&ddsd, 0, sizeof(ddsd));
817 ddsd.dwSize = sizeof(ddsd);
818 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
819 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
822 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
823 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
824 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
829 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
830 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
835 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
836 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
837 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
838 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
839 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
840 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
841 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
842 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
843 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
844 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
847 win_skip("Tests would crash on W2K with a refdevice\n");
851 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
852 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
853 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
854 set_viewport_size(device);
855 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
856 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
858 /* Draw without textures - Should result in a white quad */
859 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
860 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
862 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
863 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
864 set_viewport_size(device);
866 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
867 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
869 /* This time with the texture */
870 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
871 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
873 IDirect3DDevice7_EndScene(device);
876 /* Center quad - should be white */
877 color = getPixelColor(device, 320, 240);
878 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
879 /* Some quad in the cleared part of the texture */
880 color = getPixelColor(device, 170, 240);
881 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
882 /* Part of the originally cleared back buffer */
883 color = getPixelColor(device, 10, 10);
884 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
886 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
887 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
888 * the offscreen rendering mode this test would succeed or fail
890 color = getPixelColor(device, 10, 470);
891 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
895 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
896 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetTexture returned %#x.\n", hr);
900 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
901 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetRenderTarget returned %#x.\n", hr);
902 IDirectDrawSurface7_Release(backbuffer);
905 IDirectDrawSurface7_Release(offscreen);
909 static void alpha_test(IDirect3DDevice7 *device)
912 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
913 DWORD color, red, green, blue;
916 struct vertex quad1[] =
918 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
919 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
920 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
921 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
923 struct vertex quad2[] =
925 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
926 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
927 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
928 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
930 static float composite_quad[][5] = {
931 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
932 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
933 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
934 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
937 /* Clear the render target with alpha = 0.5 */
938 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
939 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
941 memset(&ddsd, 0, sizeof(ddsd));
942 ddsd.dwSize = sizeof(ddsd);
943 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
946 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
947 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
948 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
949 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
950 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
951 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000ff;
952 U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
953 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
954 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
958 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
959 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
964 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
965 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
966 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
967 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
968 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
969 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
970 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
971 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
973 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
974 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
977 win_skip("Tests would crash on W2K with a refdevice\n");
981 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
983 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
984 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
987 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
988 * They give essentially ZERO and ONE blend factors
990 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
991 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
992 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
993 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
994 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
995 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
997 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
998 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
999 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1000 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1001 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1002 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1004 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
1005 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
1006 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
1007 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
1010 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
1011 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1012 set_viewport_size(device);
1013 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1014 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1016 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1017 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1018 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1019 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1020 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
1021 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1023 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
1024 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1025 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1026 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1027 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1028 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1030 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
1031 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1032 set_viewport_size(device);
1034 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1035 * Disable alpha blending for the final composition
1037 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
1038 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1040 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
1041 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1042 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
1043 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1044 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
1045 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1047 hr = IDirect3DDevice7_EndScene(device);
1048 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1051 color = getPixelColor(device, 160, 360);
1052 red = (color & 0x00ff0000) >> 16;
1053 green = (color & 0x0000ff00) >> 8;
1054 blue = (color & 0x000000ff);
1055 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1056 "SRCALPHA on frame buffer returned color 0x%08x, expected 0x00bf4000\n", color);
1058 color = getPixelColor(device, 160, 120);
1059 red = (color & 0x00ff0000) >> 16;
1060 green = (color & 0x0000ff00) >> 8;
1061 blue = (color & 0x000000ff);
1062 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
1063 "DSTALPHA on frame buffer returned color 0x%08x, expected 0x000000ff\n", color);
1065 color = getPixelColor(device, 480, 360);
1066 red = (color & 0x00ff0000) >> 16;
1067 green = (color & 0x0000ff00) >> 8;
1068 blue = (color & 0x000000ff);
1069 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1070 "SRCALPHA on texture returned color 0x%08x, expected 0x00bf4000\n", color);
1072 color = getPixelColor(device, 480, 120);
1073 red = (color & 0x00ff0000) >> 16;
1074 green = (color & 0x0000ff00) >> 8;
1075 blue = (color & 0x000000ff);
1076 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
1077 "DSTALPHA on texture returned color 0x%08x, expected 0x00800080\n", color);
1080 if(offscreen) IDirectDrawSurface7_Release(offscreen);
1081 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
1084 static void rhw_zero_test(IDirect3DDevice7 *device)
1086 /* Test if it will render a quad correctly when vertex rhw = 0 */
1096 {0, 100, 0, 0, 0xffffffff},
1097 {0, 0, 0, 0, 0xffffffff},
1098 {100, 100, 0, 0, 0xffffffff},
1099 {100, 0, 0, 0, 0xffffffff},
1102 /* Clear to black */
1103 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
1104 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1106 hr = IDirect3DDevice7_BeginScene(device);
1107 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
1109 if (SUCCEEDED(hr)) {
1110 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
1111 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1113 hr = IDirect3DDevice7_EndScene(device);
1114 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1117 color = getPixelColor(device, 5, 5);
1118 ok(color == 0xffffff ||
1119 broken(color == 0), /* VMware */
1120 "Got color %08x, expected 00ffffff\n", color);
1122 color = getPixelColor(device, 105, 105);
1123 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1126 static BOOL D3D1_createObjects(void)
1131 D3DEXECUTEBUFFERDESC exdesc;
1132 D3DVIEWPORT vp_data;
1134 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1135 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1137 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1142 wc.lpfnWndProc = DefWindowProc;
1143 wc.lpszClassName = "texturemapblend_test_wc";
1145 window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1147 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1148 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1153 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
1155 /* 24 bit is fine too */
1156 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
1158 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1163 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1164 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1169 memset(&ddsd, 0, sizeof(ddsd));
1170 ddsd.dwSize = sizeof(ddsd);
1171 ddsd.dwFlags = DDSD_CAPS;
1172 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
1173 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1174 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1179 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
1181 trace("Creating a HAL device failed, trying Ref\n");
1182 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
1184 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
1189 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1190 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1195 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1196 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1197 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1198 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1199 vp_data.dwSize = sizeof(vp_data);
1202 vp_data.dwWidth = 640;
1203 vp_data.dwHeight = 480;
1204 vp_data.dvScaleX = 1;
1205 vp_data.dvScaleY = 1;
1206 vp_data.dvMaxX = 640;
1207 vp_data.dvMaxY = 480;
1210 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1211 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1213 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1214 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1215 exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1216 exdesc.dwBufferSize = 512;
1217 exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
1218 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
1219 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
1227 static void D3D1_releaseObjects(void)
1229 if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1230 if(Surface1) IDirectDrawSurface_Release(Surface1);
1231 if(Viewport) IDirect3DViewport_Release(Viewport);
1232 if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1233 if(Direct3D1) IDirect3D_Release(Direct3D1);
1234 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1235 if(window) DestroyWindow(window);
1238 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
1243 RECT rectToLock = {x, y, x+1, y+1};
1244 IDirectDrawSurface *surf = NULL;
1246 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
1247 * to an offscreen surface and lock it instead of the front buffer
1249 memset(&ddsd, 0, sizeof(ddsd));
1250 ddsd.dwSize = sizeof(ddsd);
1251 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1252 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
1254 ddsd.dwHeight = 480;
1255 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
1256 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
1257 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
1260 trace("cannot create helper surface\n");
1264 memset(&ddsd, 0, sizeof(ddsd));
1265 ddsd.dwSize = sizeof(ddsd);
1266 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1268 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
1269 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
1272 trace("Cannot blit\n");
1277 hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
1280 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
1285 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
1286 * really important for these tests
1288 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
1289 hr = IDirectDrawSurface_Unlock(surf, NULL);
1292 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
1296 IDirectDrawSurface_Release(surf);
1300 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
1301 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
1302 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
1303 ((D3DINSTRUCTION*)(ptr))->wCount = count;\
1304 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1306 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
1307 U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
1308 U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
1309 ptr = ((D3DSTATE*)(ptr))+1; } while (0)
1311 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
1312 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
1313 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
1314 ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1315 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1316 ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1317 ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1318 ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1319 ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1320 ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1321 ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1323 #define EXEBUF_END(ptr) do {\
1324 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1325 ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1326 ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1327 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1329 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1330 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1331 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1332 ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1333 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1334 U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1335 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1336 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1337 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1338 ptr = ((D3DTRIANGLE*)ptr)+1;\
1339 U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1340 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1341 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1342 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1343 ptr = ((D3DTRIANGLE*)(ptr))+1;\
1346 static HRESULT CALLBACK TextureFormatEnumCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext)
1348 if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1349 *(BOOL*)lpContext = TRUE;
1352 return DDENUMRET_OK;
1355 static void D3D1_TextureMapBlendTest(void)
1359 D3DEXECUTEBUFFERDESC exdesc;
1360 D3DEXECUTEDATA exdata;
1362 RECT rect = { 0, 0, 64, 128 };
1363 DWORD color, red, blue, green;
1364 void *exe_buffer_ptr;
1366 D3DTEXTUREHANDLE htex;
1368 IDirectDrawSurface *TexSurface = NULL;
1369 IDirect3DTexture *Texture = NULL;
1370 IDirectDrawPalette *Palette = NULL;
1371 PALETTEENTRY table1[256];
1372 BOOL p8_textures_supported = FALSE;
1382 {0.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1383 {640.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1384 {640.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1385 {0.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1386 {0.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1387 {640.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1388 {640.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1389 {0.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1392 {0.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1393 {640.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1394 {640.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1395 {0.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1396 {0.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1397 {640.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1398 {640.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1399 {0.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1402 /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1403 memset (&ddsd, 0, sizeof (ddsd));
1404 ddsd.dwSize = sizeof (ddsd);
1405 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1406 ddsd.dwHeight = 128;
1408 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1409 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1410 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1411 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1412 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1413 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1414 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1415 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1416 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1417 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1419 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1423 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1425 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1427 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1431 memset(&ddbltfx, 0, sizeof(ddbltfx));
1432 ddbltfx.dwSize = sizeof(ddbltfx);
1433 U5(ddbltfx).dwFillColor = 0;
1434 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1435 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1437 U5(ddbltfx).dwFillColor = 0xff0000ff;
1438 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1439 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1440 U5(ddbltfx).dwFillColor = 0x800000ff;
1441 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1442 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1444 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1445 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1446 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1447 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1449 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1453 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1455 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1457 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1459 EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1460 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, exe_buffer_ptr);
1461 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE, FALSE, exe_buffer_ptr);
1462 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE, FALSE, exe_buffer_ptr);
1463 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE, FALSE, exe_buffer_ptr);
1464 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_NEAREST, exe_buffer_ptr);
1465 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_NEAREST, exe_buffer_ptr);
1466 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE , D3DFILL_SOLID, exe_buffer_ptr);
1467 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA, exe_buffer_ptr);
1468 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA, exe_buffer_ptr);
1469 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1470 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, exe_buffer_ptr);
1471 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1472 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1473 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1475 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1476 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1478 EXEBUF_END(exe_buffer_ptr);
1480 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1482 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1484 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1487 memset(&exdata, 0, sizeof(exdata));
1488 exdata.dwSize = sizeof(exdata);
1489 exdata.dwVertexCount = 8;
1490 exdata.dwInstructionOffset = sizeof(test1_quads);
1491 exdata.dwInstructionLength = exe_length;
1492 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1493 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1495 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1496 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1498 if (SUCCEEDED(hr)) {
1499 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1500 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1501 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1502 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1505 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1506 red = (color & 0x00ff0000) >> 16;
1507 green = (color & 0x0000ff00) >> 8;
1508 blue = (color & 0x000000ff);
1509 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1511 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1512 red = (color & 0x00ff0000) >> 16;
1513 green = (color & 0x0000ff00) >> 8;
1514 blue = (color & 0x000000ff);
1515 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1517 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1518 red = (color & 0x00ff0000) >> 16;
1519 green = (color & 0x0000ff00) >> 8;
1520 blue = (color & 0x000000ff);
1521 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1523 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1524 red = (color & 0x00ff0000) >> 16;
1525 green = (color & 0x0000ff00) >> 8;
1526 blue = (color & 0x000000ff);
1527 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1529 /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1530 if(Texture) IDirect3DTexture_Release(Texture);
1532 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1535 memset (&ddsd, 0, sizeof (ddsd));
1536 ddsd.dwSize = sizeof (ddsd);
1537 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1538 ddsd.dwHeight = 128;
1540 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1541 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1542 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1543 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1544 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1545 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1546 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1548 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1549 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1551 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1555 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1557 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1559 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1563 memset(&ddbltfx, 0, sizeof(ddbltfx));
1564 ddbltfx.dwSize = sizeof(ddbltfx);
1565 U5(ddbltfx).dwFillColor = 0;
1566 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1567 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1569 U5(ddbltfx).dwFillColor = 0xff0000ff;
1570 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1571 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1572 U5(ddbltfx).dwFillColor = 0x800000ff;
1573 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1574 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1576 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1577 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1578 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1579 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1581 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1585 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1587 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1589 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1591 EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1592 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1593 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1594 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1596 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1597 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1599 EXEBUF_END(exe_buffer_ptr);
1601 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1603 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1605 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1608 memset(&exdata, 0, sizeof(exdata));
1609 exdata.dwSize = sizeof(exdata);
1610 exdata.dwVertexCount = 8;
1611 exdata.dwInstructionOffset = sizeof(test1_quads);
1612 exdata.dwInstructionLength = exe_length;
1613 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1614 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1616 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1617 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1619 if (SUCCEEDED(hr)) {
1620 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1621 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1622 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1623 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1626 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1627 red = (color & 0x00ff0000) >> 16;
1628 green = (color & 0x0000ff00) >> 8;
1629 blue = (color & 0x000000ff);
1630 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1632 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1633 red = (color & 0x00ff0000) >> 16;
1634 green = (color & 0x0000ff00) >> 8;
1635 blue = (color & 0x000000ff);
1636 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1638 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1639 red = (color & 0x00ff0000) >> 16;
1640 green = (color & 0x0000ff00) >> 8;
1641 blue = (color & 0x000000ff);
1642 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1644 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1645 red = (color & 0x00ff0000) >> 16;
1646 green = (color & 0x0000ff00) >> 8;
1647 blue = (color & 0x000000ff);
1648 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1650 /* 3) Test RGB - should multiply color components from diffuse color and texture */
1651 if(Texture) IDirect3DTexture_Release(Texture);
1653 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1656 memset (&ddsd, 0, sizeof (ddsd));
1657 ddsd.dwSize = sizeof (ddsd);
1658 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1659 ddsd.dwHeight = 128;
1661 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1662 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1663 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1664 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1665 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1666 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1667 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1668 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1669 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1670 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1672 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1676 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1678 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1680 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1684 memset(&ddbltfx, 0, sizeof(ddbltfx));
1685 ddbltfx.dwSize = sizeof(ddbltfx);
1686 U5(ddbltfx).dwFillColor = 0;
1687 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1688 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1690 U5(ddbltfx).dwFillColor = 0x00ffffff;
1691 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1692 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1693 U5(ddbltfx).dwFillColor = 0x00ffff80;
1694 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1695 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1697 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1698 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1699 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1700 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1702 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1706 memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1708 exe_buffer_ptr = sizeof(test2_quads) + (char*)exdesc.lpData;
1710 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1712 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1713 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1714 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1715 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1716 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1718 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1719 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1721 EXEBUF_END(exe_buffer_ptr);
1723 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test2_quads);
1725 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1727 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1730 memset(&exdata, 0, sizeof(exdata));
1731 exdata.dwSize = sizeof(exdata);
1732 exdata.dwVertexCount = 8;
1733 exdata.dwInstructionOffset = sizeof(test2_quads);
1734 exdata.dwInstructionLength = exe_length;
1735 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1736 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1738 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1739 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1741 if (SUCCEEDED(hr)) {
1742 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1743 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1744 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1745 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1748 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1749 red = (color & 0x00ff0000) >> 16;
1750 green = (color & 0x0000ff00) >> 8;
1751 blue = (color & 0x000000ff);
1752 ok(red == 0xff && green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1754 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1755 red = (color & 0x00ff0000) >> 16;
1756 green = (color & 0x0000ff00) >> 8;
1757 blue = (color & 0x000000ff);
1758 ok(red == 0xff && green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1760 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1761 red = (color & 0x00ff0000) >> 16;
1762 green = (color & 0x0000ff00) >> 8;
1763 blue = (color & 0x000000ff);
1764 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1766 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1767 red = (color & 0x00ff0000) >> 16;
1768 green = (color & 0x0000ff00) >> 8;
1769 blue = (color & 0x000000ff);
1770 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1772 /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1773 if(Texture) IDirect3DTexture_Release(Texture);
1775 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1778 memset (&ddsd, 0, sizeof (ddsd));
1779 ddsd.dwSize = sizeof (ddsd);
1780 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1781 ddsd.dwHeight = 128;
1783 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1784 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1785 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1786 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
1787 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xf800;
1788 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07e0;
1789 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001f;
1791 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1792 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1794 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1798 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1800 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1802 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1806 memset(&ddbltfx, 0, sizeof(ddbltfx));
1807 ddbltfx.dwSize = sizeof(ddbltfx);
1808 U5(ddbltfx).dwFillColor = 0;
1809 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1810 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1811 U5(ddbltfx).dwFillColor = 0xf800;
1812 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1813 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1814 U5(ddbltfx).dwFillColor = 0x001f;
1815 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1816 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1818 clrKey.dwColorSpaceLowValue = 0x001f;
1819 clrKey.dwColorSpaceHighValue = 0x001f;
1820 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1821 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1823 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1824 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1825 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1826 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1828 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1832 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1834 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1836 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1838 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1839 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1840 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1841 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1842 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1844 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1845 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1847 EXEBUF_END(exe_buffer_ptr);
1849 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1851 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1853 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1856 memset(&exdata, 0, sizeof(exdata));
1857 exdata.dwSize = sizeof(exdata);
1858 exdata.dwVertexCount = 8;
1859 exdata.dwInstructionOffset = sizeof(test1_quads);
1860 exdata.dwInstructionLength = exe_length;
1861 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1862 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1864 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1865 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1867 if (SUCCEEDED(hr)) {
1868 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1869 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1870 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1871 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1874 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1875 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1877 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1878 red = (color & 0x00ff0000) >> 16;
1879 green = (color & 0x0000ff00) >> 8;
1880 blue = (color & 0x000000ff);
1881 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1883 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1884 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1886 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1887 red = (color & 0x00ff0000) >> 16;
1888 green = (color & 0x0000ff00) >> 8;
1889 blue = (color & 0x000000ff);
1890 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1892 /* 5) Test alpha again, now with color keyed P8 texture */
1893 if(Texture) IDirect3DTexture_Release(Texture);
1895 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1898 hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1899 &p8_textures_supported);
1900 ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1902 if (!p8_textures_supported) {
1903 skip("device has no P8 texture support, skipping test\n");
1905 memset (&ddsd, 0, sizeof (ddsd));
1906 ddsd.dwSize = sizeof (ddsd);
1907 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1908 ddsd.dwHeight = 128;
1910 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1911 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1912 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1913 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1915 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1916 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1918 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1922 memset(table1, 0, sizeof(table1));
1923 table1[0].peBlue = 0xff;
1924 table1[1].peRed = 0xff;
1926 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1927 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1929 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1933 hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1934 ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1936 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1938 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1940 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1944 memset(&ddbltfx, 0, sizeof(ddbltfx));
1945 ddbltfx.dwSize = sizeof(ddbltfx);
1946 U5(ddbltfx).dwFillColor = 0;
1947 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1948 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1949 U5(ddbltfx).dwFillColor = 0;
1950 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1951 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1952 U5(ddbltfx).dwFillColor = 1;
1953 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1954 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1956 clrKey.dwColorSpaceLowValue = 1;
1957 clrKey.dwColorSpaceHighValue = 1;
1958 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1959 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1961 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1962 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1963 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1964 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1966 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1970 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1972 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1974 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1976 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1977 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1978 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1979 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1980 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1982 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1983 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1985 EXEBUF_END(exe_buffer_ptr);
1987 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1989 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1991 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1994 memset(&exdata, 0, sizeof(exdata));
1995 exdata.dwSize = sizeof(exdata);
1996 exdata.dwVertexCount = 8;
1997 exdata.dwInstructionOffset = sizeof(test1_quads);
1998 exdata.dwInstructionLength = exe_length;
1999 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
2000 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
2002 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2003 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2005 if (SUCCEEDED(hr)) {
2006 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
2007 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
2008 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2009 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2012 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2013 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2015 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
2016 red = (color & 0x00ff0000) >> 16;
2017 green = (color & 0x0000ff00) >> 8;
2018 blue = (color & 0x000000ff);
2019 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
2021 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
2022 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2024 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
2025 red = (color & 0x00ff0000) >> 16;
2026 green = (color & 0x0000ff00) >> 8;
2027 blue = (color & 0x000000ff);
2028 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
2033 if (Palette) IDirectDrawPalette_Release(Palette);
2034 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
2035 if (Texture) IDirect3DTexture_Release(Texture);
2038 static void D3D1_ViewportClearTest(void)
2041 IDirect3DMaterial *bgMaterial = NULL;
2043 D3DMATERIALHANDLE hMat;
2044 D3DVIEWPORT vp_data;
2045 IDirect3DViewport *Viewport2 = NULL;
2046 DWORD color, red, green, blue;
2048 hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
2049 ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
2054 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
2055 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
2060 hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
2061 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
2062 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
2063 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
2064 vp_data.dwSize = sizeof(vp_data);
2067 vp_data.dwWidth = 100;
2068 vp_data.dwHeight = 100;
2069 vp_data.dvScaleX = 1;
2070 vp_data.dvScaleY = 1;
2071 vp_data.dvMaxX = 100;
2072 vp_data.dvMaxY = 100;
2075 hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
2076 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
2078 memset(&mat, 0, sizeof(mat));
2079 mat.dwSize = sizeof(mat);
2080 U1(U(mat).diffuse).r = 1.0f;
2081 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2082 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2084 hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
2085 ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
2087 hr = IDirect3DViewport_SetBackground(Viewport, hMat);
2088 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2089 hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
2090 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2092 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2093 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2095 if (SUCCEEDED(hr)) {
2098 U1(rect).x1 = U2(rect).y1 = 0;
2102 hr = IDirect3DViewport_Clear(Viewport, 1, &rect, D3DCLEAR_TARGET);
2103 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2105 memset(&mat, 0, sizeof(mat));
2106 mat.dwSize = sizeof(mat);
2107 U3(U(mat).diffuse).b = 1.0f;
2108 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2109 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2111 hr = IDirect3DViewport_Clear(Viewport2, 1, &rect, D3DCLEAR_TARGET);
2112 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2114 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2115 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2118 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2119 red = (color & 0x00ff0000) >> 16;
2120 green = (color & 0x0000ff00) >> 8;
2121 blue = (color & 0x000000ff);
2122 ok((red == 0xff && green == 0 && blue == 0) ||
2123 broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
2124 "Got color %08x, expected 00ff0000\n", color);
2126 color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
2127 red = (color & 0x00ff0000) >> 16;
2128 green = (color & 0x0000ff00) >> 8;
2129 blue = (color & 0x000000ff);
2130 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
2134 if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
2135 if (Viewport2) IDirect3DViewport_Release(Viewport2);
2138 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
2142 DDSURFACEDESC2 ddsd;
2143 RECT rectToLock = {x, y, x+1, y+1};
2144 IDirectDrawSurface4 *surf = NULL;
2146 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
2147 * to an offscreen surface and lock it instead of the front buffer
2149 memset(&ddsd, 0, sizeof(ddsd));
2150 ddsd.dwSize = sizeof(ddsd);
2151 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2152 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
2154 ddsd.dwHeight = 480;
2155 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
2156 hr = IDirectDraw4_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
2157 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2160 trace("cannot create helper surface\n");
2164 memset(&ddsd, 0, sizeof(ddsd));
2165 ddsd.dwSize = sizeof(ddsd);
2166 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2168 hr = IDirectDrawSurface4_BltFast(surf, 0, 0, Surface, NULL, 0);
2169 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
2172 trace("Cannot blit\n");
2177 hr = IDirectDrawSurface4_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
2180 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
2185 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
2186 * really important for these tests
2188 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
2189 hr = IDirectDrawSurface4_Unlock(surf, NULL);
2192 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
2196 IDirectDrawSurface4_Release(surf);
2200 static void D3D3_ViewportClearTest(void)
2203 IDirectDraw *DirectDraw1 = NULL;
2204 IDirectDraw4 *DirectDraw4 = NULL;
2205 IDirectDrawSurface4 *Primary = NULL;
2206 IDirect3D3 *Direct3D3 = NULL;
2207 IDirect3DViewport3 *Viewport3 = NULL;
2208 IDirect3DViewport3 *SmallViewport3 = NULL;
2209 IDirect3DDevice3 *Direct3DDevice3 = NULL;
2211 DDSURFACEDESC2 ddsd;
2212 D3DVIEWPORT2 vp_data;
2213 DWORD color, red, green, blue;
2215 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
2216 0.0f, 1.0f, 0.0f, 0.0f,
2217 0.0f, 0.0f, 1.0f, 0.0f,
2218 0.0f, 0.0f, 0.0f, 1.0f };
2219 struct vertex quad[] =
2221 {-1.0f, -1.0f, 0.1f, 0xffffffff},
2222 {-1.0f, 1.0f, 0.1f, 0xffffffff},
2223 { 1.0f, 1.0f, 0.1f, 0xffffffff},
2224 { 1.0f, -1.0f, 0.1f, 0xffffffff},
2227 WORD Indices[] = {0, 1, 2, 2, 3, 0};
2228 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
2230 wc.lpfnWndProc = DefWindowProc;
2231 wc.lpszClassName = "D3D3_ViewportClearTest_wc";
2233 window = CreateWindow("D3D3_ViewportClearTest_wc", "D3D3_ViewportClearTest",
2234 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2236 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2237 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2238 if(FAILED(hr)) goto out;
2240 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2241 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2242 if(FAILED(hr)) goto out;
2244 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2246 /* 24 bit is fine too */
2247 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2249 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2250 if (FAILED(hr)) goto out;
2252 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void**)&DirectDraw4);
2253 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
2254 if(FAILED(hr)) goto out;
2256 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2257 ddsd.dwSize = sizeof(DDSURFACEDESC2);
2258 ddsd.dwFlags = DDSD_CAPS;
2259 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
2261 hr = IDirectDraw_CreateSurface(DirectDraw4, &ddsd, &Primary, NULL);
2262 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2263 if(FAILED(hr)) goto out;
2265 hr = IDirectDraw4_QueryInterface(DirectDraw4, &IID_IDirect3D3, (void**)&Direct3D3);
2266 ok(hr==DD_OK, "IDirectDraw4_QueryInterface returned: %08x\n", hr);
2267 if(FAILED(hr)) goto out;
2269 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DHALDevice, Primary, &Direct3DDevice3, NULL);
2271 trace("Creating a HAL device failed, trying Ref\n");
2272 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DRefDevice, Primary, &Direct3DDevice3, NULL);
2274 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
2275 if(FAILED(hr)) goto out;
2277 hr = IDirect3D3_CreateViewport(Direct3D3, &Viewport3, NULL);
2278 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2279 if(FAILED(hr)) goto out;
2281 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, Viewport3);
2282 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2284 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2285 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2286 vp_data.dwWidth = 640;
2287 vp_data.dwHeight = 480;
2288 vp_data.dvClipX = -1.0f;
2289 vp_data.dvClipWidth = 2.0f;
2290 vp_data.dvClipY = 1.0f;
2291 vp_data.dvClipHeight = 2.0f;
2292 vp_data.dvMaxZ = 1.0f;
2293 hr = IDirect3DViewport3_SetViewport2(Viewport3, &vp_data);
2294 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2296 hr = IDirect3D3_CreateViewport(Direct3D3, &SmallViewport3, NULL);
2297 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2298 if(FAILED(hr)) goto out;
2300 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, SmallViewport3);
2301 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2303 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2304 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2307 vp_data.dwWidth = 100;
2308 vp_data.dwHeight = 100;
2309 vp_data.dvClipX = -1.0f;
2310 vp_data.dvClipWidth = 2.0f;
2311 vp_data.dvClipY = 1.0f;
2312 vp_data.dvClipHeight = 2.0f;
2313 vp_data.dvMaxZ = 1.0f;
2314 hr = IDirect3DViewport3_SetViewport2(SmallViewport3, &vp_data);
2315 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2317 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2318 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2320 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
2321 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2322 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
2323 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2324 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
2325 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2326 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CLIPPING, FALSE);
2327 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2328 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ZENABLE, FALSE);
2329 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2330 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_FOGENABLE, FALSE);
2331 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2332 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_STENCILENABLE, FALSE);
2333 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2334 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
2335 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2336 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
2337 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2338 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
2339 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState failed with %08x\n", hr);
2340 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
2341 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2343 if (SUCCEEDED(hr)) {
2344 U1(rect).x1 = U2(rect).y1 = 0;
2348 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x00ff00, 0.0f, 0);
2349 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2351 hr = IDirect3DViewport3_Clear2(SmallViewport3, 1, &rect, D3DCLEAR_TARGET, 0xff0000, 0.0f, 0);
2352 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2354 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2355 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2358 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2359 red = (color & 0x00ff0000) >> 16;
2360 green = (color & 0x0000ff00) >> 8;
2361 blue = (color & 0x000000ff);
2362 ok(red == 0 && green == 0xff && blue == 0, "Got color %08x, expected 0000ff00\n", color);
2364 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2365 red = (color & 0x00ff0000) >> 16;
2366 green = (color & 0x0000ff00) >> 8;
2367 blue = (color & 0x000000ff);
2368 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000\n", color);
2370 /* Test that clearing viewport doesn't interfere with rendering to previously active viewport. */
2371 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2372 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2374 if (SUCCEEDED(hr)) {
2375 hr = IDirect3DDevice3_SetCurrentViewport(Direct3DDevice3, SmallViewport3);
2376 ok(hr == D3D_OK, "IDirect3DDevice3_SetCurrentViewport failed with %08x\n", hr);
2378 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x000000, 0.0f, 0);
2379 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2381 hr = IDirect3DDevice3_DrawIndexedPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf, quad, 4 /* NumVerts */,
2382 Indices, 6 /* Indexcount */, 0 /* flags */);
2383 ok(hr == D3D_OK, "IDirect3DDevice3_DrawIndexedPrimitive failed with %08x\n", hr);
2385 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2386 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2389 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2390 red = (color & 0x00ff0000) >> 16;
2391 green = (color & 0x0000ff00) >> 8;
2392 blue = (color & 0x000000ff);
2393 ok(red == 0 && green == 0 && blue == 0, "Got color %08x, expected 00000000\n", color);
2395 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2396 red = (color & 0x00ff0000) >> 16;
2397 green = (color & 0x0000ff00) >> 8;
2398 blue = (color & 0x000000ff);
2399 ok(red == 0xff && green == 0xff && blue == 0xff, "Got color %08x, expected 00ffffff\n", color);
2403 if (SmallViewport3) IDirect3DViewport3_Release(SmallViewport3);
2404 if (Viewport3) IDirect3DViewport3_Release(Viewport3);
2405 if (Direct3DDevice3) IDirect3DDevice3_Release(Direct3DDevice3);
2406 if (Direct3D3) IDirect3D3_Release(Direct3D3);
2407 if (Primary) IDirectDrawSurface4_Release(Primary);
2408 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
2409 if (DirectDraw4) IDirectDraw4_Release(DirectDraw4);
2410 if(window) DestroyWindow(window);
2413 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
2420 memset(&ddsd, 0, sizeof(ddsd));
2421 ddsd.dwSize = sizeof(ddsd);
2423 hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
2424 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2426 p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2428 for (i = 0; i < h; i++) {
2429 for (i1 = 0; i1 < w; i1++) {
2432 p += U1(ddsd).lPitch;
2435 hr = IDirectDrawSurface_Unlock(dest, NULL);
2436 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2439 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
2441 COLORREF clr = CLR_INVALID;
2445 hr = IDirectDrawSurface_GetDC(Surface, &hdc);
2446 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2448 if (SUCCEEDED(hr)) {
2449 clr = GetPixel(hdc, x, y);
2451 hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
2452 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2458 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
2462 for (i = 0; i < 256; i++) {
2463 if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
2464 table1[i].peBlue != table2[i].rgbBlue) return FALSE;
2470 static void p8_primary_test(void)
2472 /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
2476 PALETTEENTRY entries[256];
2477 RGBQUAD coltable[256];
2479 IDirectDrawPalette *ddprimpal = NULL;
2480 IDirectDrawSurface *offscreen = NULL;
2486 unsigned differences;
2488 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
2489 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
2491 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2496 wc.lpfnWndProc = DefWindowProc;
2497 wc.lpszClassName = "p8_primary_test_wc";
2499 window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2501 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2502 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2507 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
2508 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2513 memset(&ddsd, 0, sizeof(ddsd));
2514 ddsd.dwSize = sizeof(ddsd);
2515 ddsd.dwFlags = DDSD_CAPS;
2516 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2517 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
2518 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
2523 memset(entries, 0, sizeof(entries));
2524 entries[0].peRed = 0xff;
2525 entries[1].peGreen = 0xff;
2526 entries[2].peBlue = 0xff;
2528 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
2529 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2531 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
2535 hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
2536 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2538 p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
2540 color = getPixelColor_GDI(Surface1, 10, 10);
2541 ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
2542 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2543 GetRValue(color), GetGValue(color), GetBValue(color));
2545 memset(&ddbltfx, 0, sizeof(ddbltfx));
2546 ddbltfx.dwSize = sizeof(ddbltfx);
2547 U5(ddbltfx).dwFillColor = 0;
2548 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2549 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2551 color = getPixelColor_GDI(Surface1, 10, 10);
2552 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
2553 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
2554 GetRValue(color), GetGValue(color), GetBValue(color));
2556 memset(&ddbltfx, 0, sizeof(ddbltfx));
2557 ddbltfx.dwSize = sizeof(ddbltfx);
2558 U5(ddbltfx).dwFillColor = 1;
2559 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2560 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2562 color = getPixelColor_GDI(Surface1, 10, 10);
2563 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2564 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2565 GetRValue(color), GetGValue(color), GetBValue(color));
2567 memset (&ddsd, 0, sizeof (ddsd));
2568 ddsd.dwSize = sizeof (ddsd);
2569 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2572 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
2573 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2574 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2575 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2576 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2578 broken(hr == DDERR_INVALIDPIXELFORMAT) || /* VMware */
2579 broken(hr == DDERR_NODIRECTDRAWHW), /* VMware */
2580 "IDirectDraw_CreateSurface returned %08x\n", hr);
2581 if (FAILED(hr)) goto out;
2583 memset(entries, 0, sizeof(entries));
2584 for (i = 0; i < 256; i++) {
2585 entries[i].peBlue = i;
2587 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2588 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2590 hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
2591 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2592 i = GetDIBColorTable(hdc, 0, 256, coltable);
2593 ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
2594 hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
2595 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2597 ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
2599 p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 2);
2601 memset(entries, 0, sizeof(entries));
2602 entries[0].peRed = 0xff;
2603 entries[1].peGreen = 0xff;
2604 entries[2].peBlue = 0xff;
2605 entries[3].peRed = 0x80;
2606 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2607 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2609 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2610 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2612 color = getPixelColor_GDI(Surface1, 1, 1);
2613 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2614 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2615 GetRValue(color), GetGValue(color), GetBValue(color));
2617 /* Color keyed blit. */
2618 p8_surface_fill_rect(offscreen, 0, 0, 8, 8, 3);
2619 clrKey.dwColorSpaceLowValue = 3;
2620 clrKey.dwColorSpaceHighValue = 3;
2621 hr = IDirectDrawSurface_SetColorKey(offscreen, DDCKEY_SRCBLT, &clrKey);
2622 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
2624 hr = IDirectDrawSurface_BltFast(Surface1, 100, 100, offscreen, NULL, DDBLTFAST_SRCCOLORKEY);
2625 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2627 color = getPixelColor_GDI(Surface1, 105, 105);
2628 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2629 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2630 GetRValue(color), GetGValue(color), GetBValue(color));
2632 color = getPixelColor_GDI(Surface1, 112, 112);
2633 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2634 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2635 GetRValue(color), GetGValue(color), GetBValue(color));
2642 memset(&ddbltfx, 0, sizeof(ddbltfx));
2643 ddbltfx.dwSize = sizeof(ddbltfx);
2644 ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 2;
2645 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2646 DDBLT_WAIT | DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2647 ok(hr==DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned: %x\n", hr);
2648 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2649 DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2650 ok(hr==DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2652 color = getPixelColor_GDI(Surface1, 105, 205);
2653 ok(GetRValue(color) == 0x80 && GetGValue(color) == 0 && GetBValue(color) == 0,
2654 "got R %02X G %02X B %02X, expected R 80 G 00 B 00\n",
2655 GetRValue(color), GetGValue(color), GetBValue(color));
2657 color = getPixelColor_GDI(Surface1, 112, 212);
2658 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2659 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2660 GetRValue(color), GetGValue(color), GetBValue(color));
2662 /* Test blitting and locking patterns that are likely to trigger bugs in opengl renderer (p8
2663 surface conversion and uploading/downloading to/from opengl texture). Similar patterns (
2664 blitting front buffer areas to/from an offscreen surface mixed with locking) are used by C&C
2666 IDirectDrawSurface_Release(offscreen);
2668 memset (&ddsd, 0, sizeof (ddsd));
2669 ddsd.dwSize = sizeof (ddsd);
2670 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2672 ddsd.dwHeight = 480;
2673 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2674 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2675 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2676 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2677 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2678 ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
2680 if (FAILED(hr)) goto out;
2682 /* Test two times, first time front buffer has a palette and second time front buffer
2683 has no palette; the latter is somewhat contrived example, but an app could set
2684 front buffer palette later. */
2685 for (i2 = 0; i2 < 2; i2++) {
2687 hr = IDirectDrawSurface_SetPalette(Surface1, NULL);
2688 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2691 memset(&ddsd, 0, sizeof(ddsd));
2692 ddsd.dwSize = sizeof(ddsd);
2693 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2694 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2696 for (i = 0; i < 256; i++) {
2697 unsigned x = (i % 128) * 4;
2698 unsigned y = (i / 128) * 4;
2699 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2701 for (i1 = 0; i1 < 4; i1++) {
2702 p[0] = p[1] = p[2] = p[3] = i;
2703 p += U1(ddsd).lPitch;
2707 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2708 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2710 hr = IDirectDrawSurface_BltFast(offscreen, 0, 0, Surface1, NULL, 0);
2711 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2713 /* This ensures offscreen surface contents will be downloaded to system memory. */
2714 memset(&ddsd, 0, sizeof(ddsd));
2715 ddsd.dwSize = sizeof(ddsd);
2716 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2717 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2718 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2719 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2721 /* Offscreen surface data will have to be converted and uploaded to texture. */
2726 hr = IDirectDrawSurface_BltFast(offscreen, 600, 400, Surface1, &rect, 0);
2727 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2729 /* This ensures offscreen surface contents will be downloaded to system memory. */
2730 memset(&ddsd, 0, sizeof(ddsd));
2731 ddsd.dwSize = sizeof(ddsd);
2732 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2733 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2734 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2735 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2737 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2738 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2740 memset(&ddsd, 0, sizeof(ddsd));
2741 ddsd.dwSize = sizeof(ddsd);
2742 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2743 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2747 for (i = 0; i < 256; i++) {
2748 unsigned x = (i % 128) * 4 + 1;
2749 unsigned y = (i / 128) * 4 + 1;
2750 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2752 if (*p != i) differences++;
2755 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2756 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2758 ok(differences == 0, i2 == 0 ? "Pass 1. Unexpected front buffer contents after blit (%u differences)\n" :
2759 "Pass 2 (with NULL front buffer palette). Unexpected front buffer contents after blit (%u differences)\n",
2765 if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
2766 if(offscreen) IDirectDrawSurface_Release(offscreen);
2767 if(Surface1) IDirectDrawSurface_Release(Surface1);
2768 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
2769 if(window) DestroyWindow(window);
2772 static void cubemap_test(IDirect3DDevice7 *device)
2775 IDirectDraw7 *ddraw;
2776 IDirectDrawSurface7 *cubemap, *surface;
2777 D3DDEVICEDESC7 d3dcaps;
2780 DDSURFACEDESC2 ddsd;
2783 static float quad[] = {
2784 -1.0, -1.0, 0.1, 1.0, 0.0, 0.0, /* Lower left */
2785 0.0, -1.0, 0.1, 1.0, 0.0, 0.0,
2786 -1.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2787 0.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2789 0.0, -1.0, 0.1, 0.0, 1.0, 0.0, /* Lower right */
2790 1.0, -1.0, 0.1, 0.0, 1.0, 0.0,
2791 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2792 1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2794 0.0, 0.0, 0.1, 0.0, 0.0, 1.0, /* upper right */
2795 1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
2796 0.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2797 1.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2799 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, /* Upper left */
2800 0.0, 0.0, 0.1, -1.0, 0.0, 0.0,
2801 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2802 0.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2805 memset(&DDBltFx, 0, sizeof(DDBltFx));
2806 DDBltFx.dwSize = sizeof(DDBltFx);
2808 memset(&d3dcaps, 0, sizeof(d3dcaps));
2809 hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
2810 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2811 if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2813 skip("No cubemap support\n");
2817 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2818 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
2820 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2821 ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
2822 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
2823 ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
2824 IDirect3D7_Release(d3d);
2827 memset(&ddsd, 0, sizeof(ddsd));
2828 ddsd.dwSize = sizeof(ddsd);
2829 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2830 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2833 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2834 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
2835 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2836 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2837 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2838 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2839 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2841 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
2842 ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
2843 IDirectDraw7_Release(ddraw);
2846 U5(DDBltFx).dwFillColor = 0x00ff0000;
2847 hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2848 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2850 memset(&caps, 0, sizeof(caps));
2851 caps.dwCaps = DDSCAPS_TEXTURE;
2852 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
2853 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2854 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2855 U5(DDBltFx).dwFillColor = 0x0000ffff;
2856 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2857 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2859 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
2860 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2861 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2862 U5(DDBltFx).dwFillColor = 0x0000ff00;
2863 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2864 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2866 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
2867 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2868 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2869 U5(DDBltFx).dwFillColor = 0x000000ff;
2870 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2871 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2873 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2874 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2875 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2876 U5(DDBltFx).dwFillColor = 0x00ffff00;
2877 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2878 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2880 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2881 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2882 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2883 U5(DDBltFx).dwFillColor = 0x00ff00ff;
2884 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2885 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2887 hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2888 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2889 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2890 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2891 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2892 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2894 hr = IDirect3DDevice7_BeginScene(device);
2895 ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2898 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2899 if (hr == DDERR_UNSUPPORTED || hr == DDERR_NODIRECTDRAWHW)
2902 win_skip("IDirect3DDevice7_DrawPrimitive is not completely implemented, colors won't be tested\n");
2903 hr = IDirect3DDevice7_EndScene(device);
2904 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2907 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2908 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
2909 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2910 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 8 * 6, 4, 0);
2911 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2912 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 12* 6, 4, 0);
2913 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2915 hr = IDirect3DDevice7_EndScene(device);
2916 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2918 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2919 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2921 color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2922 ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2923 color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2924 ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2925 color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2926 ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2927 color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2928 ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2931 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2932 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2933 IDirectDrawSurface7_Release(cubemap);
2936 /* This test tests depth clamping / clipping behaviour:
2937 * - With software vertex processing, depth values are clamped to the
2938 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2939 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2940 * same as regular vertices here.
2941 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2942 * Normal vertices are always clipped. Pretransformed vertices are
2943 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2944 * - The viewport's MinZ/MaxZ is irrelevant for this.
2946 static void depth_clamp_test(IDirect3DDevice7 *device)
2948 struct tvertex quad1[] =
2950 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2951 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2952 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2953 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2955 struct tvertex quad2[] =
2957 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2958 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2959 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2960 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2962 struct tvertex quad3[] =
2964 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2965 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2966 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2967 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2969 struct tvertex quad4[] =
2971 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2972 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2973 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2974 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2976 struct vertex quad5[] =
2978 { -0.5f, 0.5f, 10.0f, 0xff14f914},
2979 { 0.5f, 0.5f, 10.0f, 0xff14f914},
2980 { -0.5f, -0.5f, 10.0f, 0xff14f914},
2981 { 0.5f, -0.5f, 10.0f, 0xff14f914},
2983 struct vertex quad6[] =
2985 { -1.0f, 0.5f, 10.0f, 0xfff91414},
2986 { 1.0f, 0.5f, 10.0f, 0xfff91414},
2987 { -1.0f, 0.25f, 10.0f, 0xfff91414},
2988 { 1.0f, 0.25f, 10.0f, 0xfff91414},
3002 hr = IDirect3DDevice7_SetViewport(device, &vp);
3003 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3005 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3006 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3008 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3009 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3010 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
3011 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3012 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZWRITEENABLE, TRUE);
3013 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3014 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
3015 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3017 hr = IDirect3DDevice7_BeginScene(device);
3018 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3020 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
3021 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3022 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad2, 4, 0);
3023 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3025 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3028 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad3, 4, 0);
3029 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3030 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad4, 4, 0);
3031 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3033 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3034 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3036 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad5, 4, 0);
3037 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3039 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3040 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3042 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad6, 4, 0);
3043 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3045 hr = IDirect3DDevice7_EndScene(device);
3046 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3048 color = getPixelColor(device, 75, 75);
3049 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3050 color = getPixelColor(device, 150, 150);
3051 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3052 color = getPixelColor(device, 320, 240);
3053 ok(color_match(color, 0x00002b7f, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3054 color = getPixelColor(device, 320, 330);
3055 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3056 color = getPixelColor(device, 320, 330);
3057 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3061 hr = IDirect3DDevice7_SetViewport(device, &vp);
3062 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3065 static void DX1_BackBufferFlipTest(void)
3068 IDirectDraw *DirectDraw1 = NULL;
3069 IDirectDrawSurface *Primary = NULL;
3070 IDirectDrawSurface *Backbuffer = NULL;
3075 const DWORD white = 0xffffff;
3076 const DWORD red = 0xff0000;
3077 BOOL attached = FALSE;
3079 wc.lpfnWndProc = DefWindowProc;
3080 wc.lpszClassName = "DX1_BackBufferFlipTest_wc";
3082 window = CreateWindow("DX1_BackBufferFlipTest_wc", "DX1_BackBufferFlipTest",
3083 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3085 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
3086 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
3087 if(FAILED(hr)) goto out;
3089 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3090 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
3091 if(FAILED(hr)) goto out;
3093 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
3095 /* 24 bit is fine too */
3096 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
3098 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
3103 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3104 ddsd.dwSize = sizeof(DDSURFACEDESC);
3105 ddsd.dwFlags = DDSD_CAPS;
3106 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3108 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Primary, NULL);
3109 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3111 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3112 ddsd.dwSize = sizeof(DDSURFACEDESC);
3113 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3114 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3116 ddsd.dwHeight = 480;
3117 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3118 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3119 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
3120 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
3121 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
3122 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
3124 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Backbuffer, NULL);
3125 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3126 if(FAILED(hr)) goto out;
3128 hr = IDirectDrawSurface_AddAttachedSurface(Primary, Backbuffer);
3129 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3130 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3131 if (FAILED(hr)) goto out;
3135 memset(&ddbltfx, 0, sizeof(ddbltfx));
3136 ddbltfx.dwSize = sizeof(ddbltfx);
3137 U5(ddbltfx).dwFillColor = red;
3138 hr = IDirectDrawSurface_Blt(Backbuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3139 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3141 U5(ddbltfx).dwFillColor = white;
3142 hr = IDirectDrawSurface_Blt(Primary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3143 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3146 color = getPixelColor_GDI(Primary, 5, 5);
3147 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF,
3148 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3149 GetRValue(color), GetGValue(color), GetBValue(color));
3151 color = getPixelColor_GDI(Backbuffer, 5, 5);
3152 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3153 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3154 GetRValue(color), GetGValue(color), GetBValue(color));
3156 hr = IDirectDrawSurface_Flip(Primary, NULL, DDFLIP_WAIT);
3157 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3161 color = getPixelColor_GDI(Primary, 5, 5);
3162 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3163 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3164 GetRValue(color), GetGValue(color), GetBValue(color));
3166 color = getPixelColor_GDI(Backbuffer, 5, 5);
3167 ok((GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF) ||
3168 broken(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0), /* broken driver */
3169 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3170 GetRValue(color), GetGValue(color), GetBValue(color));
3178 IDirectDrawSurface_DeleteAttachedSurface(Primary, 0, Backbuffer);
3179 IDirectDrawSurface_Release(Backbuffer);
3181 if (Primary) IDirectDrawSurface_Release(Primary);
3182 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
3183 if (window) DestroyWindow(window);
3190 if(!createObjects())
3192 skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
3196 /* Check for the reliability of the returned data */
3197 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3200 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3204 color = getPixelColor(Direct3DDevice, 1, 1);
3205 if(color !=0x00ff0000)
3207 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3211 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3214 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3218 color = getPixelColor(Direct3DDevice, 639, 479);
3219 if(color != 0x0000ddee)
3221 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3225 /* Now run the tests */
3226 blt_test(Direct3DDevice);
3227 depth_clamp_test(Direct3DDevice);
3228 lighting_test(Direct3DDevice);
3229 clear_test(Direct3DDevice);
3230 fog_test(Direct3DDevice);
3231 offscreen_test(Direct3DDevice);
3232 alpha_test(Direct3DDevice);
3233 rhw_zero_test(Direct3DDevice);
3234 cubemap_test(Direct3DDevice);
3236 releaseObjects(); /* release DX7 interfaces to test D3D1 */
3238 if(!D3D1_createObjects()) {
3239 skip("Cannot initialize D3D1, skipping\n");
3242 D3D1_TextureMapBlendTest();
3243 D3D1_ViewportClearTest();
3245 D3D1_releaseObjects();
3247 D3D3_ViewportClearTest();
3249 DX1_BackBufferFlipTest();