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 hr = 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 hr = 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, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
564 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
565 transformed_1, 4, Indices, 6, 0);
566 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
568 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
569 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
570 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
573 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
574 transformed_2, 4, Indices, 6, 0);
575 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
577 hr = IDirect3DDevice7_EndScene(device);
578 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
582 ok(FALSE, "BeginScene failed\n");
585 color = getPixelColor(device, 160, 360);
586 ok(color_match(color, 0x00FF0000, 1), "Untransformed vertex with no table or vertex fog has color %08x\n", color);
587 color = getPixelColor(device, 160, 120);
588 ok(color_match(color, 0x0000FF00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
589 color = getPixelColor(device, 480, 120);
590 ok(color_match(color, 0x00FFFF00, 1), "Transformed vertex with linear vertex fog has color %08x\n", color);
591 if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
593 color = getPixelColor(device, 480, 360);
594 ok(color_match(color, 0x0000FF00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
598 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
599 * The settings above result in no fogging with vertex fog
601 color = getPixelColor(device, 480, 120);
602 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
603 trace("Info: Table fog not supported by this device\n");
606 if (caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
608 /* A simple fog + non-identity world matrix test */
609 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat1);
610 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %#08x\n", hr);
612 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
613 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
614 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
615 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
617 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
618 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %#08x\n", hr);
620 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
622 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
623 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad1, 4, Indices, 6, 0);
624 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
626 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
627 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad2, 4, Indices, 6, 0);
628 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
630 hr = IDirect3DDevice7_EndScene(device);
631 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
635 ok(FALSE, "BeginScene failed\n");
638 color = getPixelColor(device, 160, 360);
639 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
640 color = getPixelColor(device, 160, 120);
641 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
643 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
644 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat2);
645 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
646 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)proj_mat);
647 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
649 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
650 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
652 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
654 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
655 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_1, 4, Indices, 6, 0);
656 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
658 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
659 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_2, 4, Indices, 6, 0);
660 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
662 hr = IDirect3DDevice7_EndScene(device);
663 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
667 ok(FALSE, "BeginScene failed\n");
670 color = getPixelColor(device, 160, 360);
671 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
672 color = getPixelColor(device, 160, 120);
673 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
675 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)ident_mat);
676 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
677 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)ident_mat);
678 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
682 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
685 /* Turn off the fog master switch to avoid confusing other tests */
686 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
687 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
690 static void blt_test(IDirect3DDevice7 *device)
692 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
696 memset(&ddsd, 0, sizeof(ddsd));
697 ddsd.dwSize = sizeof(ddsd);
698 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
699 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
702 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
703 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
704 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
706 /* Offscreen blits with the same source as destination */
709 RECT src_rect, dst_rect;
711 /* Blit the whole surface to itself */
712 hr = IDirectDrawSurface_Blt(offscreen, NULL, offscreen, NULL, 0, NULL);
713 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
715 /* Overlapped blit */
716 dst_rect.left = 0; dst_rect.right = 480;
717 dst_rect.top = 0; dst_rect.bottom = 480;
718 src_rect.left = 160; src_rect.right = 640;
719 src_rect.top = 0; src_rect.bottom = 480;
720 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
721 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
723 /* Overlapped blit, flip-y through source rectangle (not allowed) */
724 dst_rect.left = 0; dst_rect.right = 480;
725 dst_rect.top = 0; dst_rect.bottom = 480;
726 src_rect.left = 160; src_rect.right = 640;
727 src_rect.top = 480; src_rect.bottom = 0;
728 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
729 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface7_Blt returned %08x\n", hr);
731 /* Overlapped blit, with shrinking in x */
732 dst_rect.left = 0; dst_rect.right = 480;
733 dst_rect.top = 0; dst_rect.bottom = 480;
734 src_rect.left = 160; src_rect.right = 480;
735 src_rect.top = 0; src_rect.bottom = 480;
736 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
737 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
740 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
741 ok(hr == D3D_OK, "Unable to obtain a surface pointer to the backbuffer, hr = %08x\n", hr);
743 /* backbuffer ==> texture blits */
744 if(SUCCEEDED(hr) && offscreen)
746 RECT src_rect, dst_rect;
748 /* backbuffer ==> texture, src_rect=NULL, dst_rect=NULL, no scaling */
749 hr = IDirectDrawSurface_Blt(offscreen, NULL, backbuffer, NULL, 0, NULL);
750 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
752 /* backbuffer ==> texture, full surface blits, no scaling */
753 dst_rect.left = 0; dst_rect.right = 640;
754 dst_rect.top = 0; dst_rect.bottom = 480;
755 src_rect.left = 0; src_rect.right = 640;
756 src_rect.top = 0; src_rect.bottom = 480;
757 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
758 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
760 /* backbuffer ==> texture, flip in y-direction through source rectangle, no scaling (allowed) */
761 dst_rect.left = 0; dst_rect.right = 640;
762 dst_rect.top = 480; dst_rect.top = 0;
763 src_rect.left = 0; src_rect.right = 640;
764 src_rect.top = 0; src_rect.bottom = 480;
765 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
766 ok(hr == DD_OK, "backbuffer => texture flip-y src_rect failed with hr = %08x\n", hr);
768 /* backbuffer ==> texture, flip in x-direction through source rectangle, no scaling (not allowed) */
769 dst_rect.left = 640; dst_rect.right = 0;
770 dst_rect.top = 0; dst_rect.top = 480;
771 src_rect.left = 0; src_rect.right = 640;
772 src_rect.top = 0; src_rect.bottom = 480;
773 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
774 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x src_rect failed with hr = %08x\n", hr);
776 /* backbuffer ==> texture, flip in y-direction through destination rectangle (not allowed) */
777 dst_rect.left = 0; dst_rect.right = 640;
778 dst_rect.top = 0; dst_rect.top = 480;
779 src_rect.left = 0; src_rect.right = 640;
780 src_rect.top = 480; src_rect.bottom = 0;
781 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
782 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-y dst_rect failed with hr = %08x\n", hr);
784 /* backbuffer ==> texture, flip in x-direction through destination rectangle, no scaling (not allowed) */
785 dst_rect.left = 0; dst_rect.right = 640;
786 dst_rect.top = 0; dst_rect.top = 480;
787 src_rect.left = 640; src_rect.right = 0;
788 src_rect.top = 0; src_rect.bottom = 480;
789 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
790 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x dst_rect failed with hr = %08x\n", hr);
793 if(offscreen) IDirectDrawSurface7_Release(offscreen);
794 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
797 static void offscreen_test(IDirect3DDevice7 *device)
800 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
804 static float quad[][5] = {
805 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
806 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
807 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
808 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
811 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
812 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
814 memset(&ddsd, 0, sizeof(ddsd));
815 ddsd.dwSize = sizeof(ddsd);
816 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
817 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
820 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
821 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
822 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
827 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
828 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
833 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
834 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
835 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
836 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
837 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
838 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
839 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
840 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
841 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
842 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
845 win_skip("Tests would crash on W2K with a refdevice\n");
849 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
850 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
851 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
852 set_viewport_size(device);
853 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
854 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
856 /* Draw without textures - Should result in a white quad */
857 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
858 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
860 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
861 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
862 set_viewport_size(device);
864 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
865 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
867 /* This time with the texture */
868 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
869 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
871 IDirect3DDevice7_EndScene(device);
874 /* Center quad - should be white */
875 color = getPixelColor(device, 320, 240);
876 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
877 /* Some quad in the cleared part of the texture */
878 color = getPixelColor(device, 170, 240);
879 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
880 /* Part of the originally cleared back buffer */
881 color = getPixelColor(device, 10, 10);
882 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
884 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
885 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
886 * the offscreen rendering mode this test would succeed or fail
888 color = getPixelColor(device, 10, 470);
889 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
893 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
894 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetTexture returned %#x.\n", hr);
898 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
899 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetRenderTarget returned %#x.\n", hr);
900 IDirectDrawSurface7_Release(backbuffer);
903 IDirectDrawSurface7_Release(offscreen);
907 static void alpha_test(IDirect3DDevice7 *device)
910 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
911 DWORD color, red, green, blue;
914 struct vertex quad1[] =
916 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
917 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
918 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
919 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
921 struct vertex quad2[] =
923 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
924 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
925 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
926 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
928 static float composite_quad[][5] = {
929 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
930 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
931 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
932 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
935 /* Clear the render target with alpha = 0.5 */
936 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
937 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
939 memset(&ddsd, 0, sizeof(ddsd));
940 ddsd.dwSize = sizeof(ddsd);
941 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
944 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
945 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
946 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
947 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
948 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
949 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000ff;
950 U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
951 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
952 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
956 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
957 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
962 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
963 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
964 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
965 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
966 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
967 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
968 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
969 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
971 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
972 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
975 win_skip("Tests would crash on W2K with a refdevice\n");
979 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
981 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
982 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
985 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
986 * They give essentially ZERO and ONE blend factors
988 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
989 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
990 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
991 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
992 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
993 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
995 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
996 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
997 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
998 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
999 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1000 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1002 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
1003 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
1004 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
1005 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
1008 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
1009 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1010 set_viewport_size(device);
1011 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1012 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1014 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1015 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1016 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1017 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1018 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
1019 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1021 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
1022 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1023 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1024 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1025 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1026 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1028 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
1029 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1030 set_viewport_size(device);
1032 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1033 * Disable alpha blending for the final composition
1035 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
1036 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1038 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
1039 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1040 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
1041 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1042 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
1043 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1045 hr = IDirect3DDevice7_EndScene(device);
1046 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1049 color = getPixelColor(device, 160, 360);
1050 red = (color & 0x00ff0000) >> 16;
1051 green = (color & 0x0000ff00) >> 8;
1052 blue = (color & 0x000000ff);
1053 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1054 "SRCALPHA on frame buffer returned color 0x%08x, expected 0x00bf4000\n", color);
1056 color = getPixelColor(device, 160, 120);
1057 red = (color & 0x00ff0000) >> 16;
1058 green = (color & 0x0000ff00) >> 8;
1059 blue = (color & 0x000000ff);
1060 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
1061 "DSTALPHA on frame buffer returned color 0x%08x, expected 0x000000ff\n", color);
1063 color = getPixelColor(device, 480, 360);
1064 red = (color & 0x00ff0000) >> 16;
1065 green = (color & 0x0000ff00) >> 8;
1066 blue = (color & 0x000000ff);
1067 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1068 "SRCALPHA on texture returned color 0x%08x, expected 0x00bf4000\n", color);
1070 color = getPixelColor(device, 480, 120);
1071 red = (color & 0x00ff0000) >> 16;
1072 green = (color & 0x0000ff00) >> 8;
1073 blue = (color & 0x000000ff);
1074 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
1075 "DSTALPHA on texture returned color 0x%08x, expected 0x00800080\n", color);
1078 if(offscreen) IDirectDrawSurface7_Release(offscreen);
1079 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
1082 static void rhw_zero_test(IDirect3DDevice7 *device)
1084 /* Test if it will render a quad correctly when vertex rhw = 0 */
1094 {0, 100, 0, 0, 0xffffffff},
1095 {0, 0, 0, 0, 0xffffffff},
1096 {100, 100, 0, 0, 0xffffffff},
1097 {100, 0, 0, 0, 0xffffffff},
1100 /* Clear to black */
1101 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
1102 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1104 hr = IDirect3DDevice7_BeginScene(device);
1105 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
1107 if (SUCCEEDED(hr)) {
1108 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
1109 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1111 hr = IDirect3DDevice7_EndScene(device);
1112 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1115 color = getPixelColor(device, 5, 5);
1116 ok(color == 0xffffff ||
1117 broken(color == 0), /* VMware */
1118 "Got color %08x, expected 00ffffff\n", color);
1120 color = getPixelColor(device, 105, 105);
1121 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1124 static BOOL D3D1_createObjects(void)
1129 D3DEXECUTEBUFFERDESC exdesc;
1130 D3DVIEWPORT vp_data;
1132 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1133 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1135 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1140 wc.lpfnWndProc = DefWindowProc;
1141 wc.lpszClassName = "texturemapblend_test_wc";
1143 window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1145 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1146 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1151 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
1153 /* 24 bit is fine too */
1154 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
1156 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1161 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1162 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1167 memset(&ddsd, 0, sizeof(ddsd));
1168 ddsd.dwSize = sizeof(ddsd);
1169 ddsd.dwFlags = DDSD_CAPS;
1170 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
1171 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1172 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1177 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
1179 trace("Creating a HAL device failed, trying Ref\n");
1180 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
1182 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
1187 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1188 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1193 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1194 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1195 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1196 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1197 vp_data.dwSize = sizeof(vp_data);
1200 vp_data.dwWidth = 640;
1201 vp_data.dwHeight = 480;
1202 vp_data.dvScaleX = 1;
1203 vp_data.dvScaleY = 1;
1204 vp_data.dvMaxX = 640;
1205 vp_data.dvMaxY = 480;
1208 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1209 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1211 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1212 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1213 exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1214 exdesc.dwBufferSize = 512;
1215 exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
1216 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
1217 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
1225 static void D3D1_releaseObjects(void)
1227 if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1228 if(Surface1) IDirectDrawSurface_Release(Surface1);
1229 if(Viewport) IDirect3DViewport_Release(Viewport);
1230 if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1231 if(Direct3D1) IDirect3D_Release(Direct3D1);
1232 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1233 if(window) DestroyWindow(window);
1236 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
1241 RECT rectToLock = {x, y, x+1, y+1};
1242 IDirectDrawSurface *surf = NULL;
1244 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
1245 * to an offscreen surface and lock it instead of the front buffer
1247 memset(&ddsd, 0, sizeof(ddsd));
1248 ddsd.dwSize = sizeof(ddsd);
1249 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1250 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
1252 ddsd.dwHeight = 480;
1253 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
1254 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
1255 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
1258 trace("cannot create helper surface\n");
1262 memset(&ddsd, 0, sizeof(ddsd));
1263 ddsd.dwSize = sizeof(ddsd);
1264 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1266 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
1267 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
1270 trace("Cannot blit\n");
1275 hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
1278 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
1283 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
1284 * really important for these tests
1286 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
1287 hr = IDirectDrawSurface_Unlock(surf, NULL);
1290 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
1294 IDirectDrawSurface_Release(surf);
1298 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
1299 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
1300 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
1301 ((D3DINSTRUCTION*)(ptr))->wCount = count;\
1302 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1304 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
1305 U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
1306 U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
1307 ptr = ((D3DSTATE*)(ptr))+1; } while (0)
1309 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
1310 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
1311 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
1312 ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1313 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1314 ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1315 ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1316 ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1317 ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1318 ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1319 ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1321 #define EXEBUF_END(ptr) do {\
1322 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1323 ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1324 ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1325 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1327 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1328 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1329 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1330 ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1331 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1332 U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1333 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1334 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1335 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1336 ptr = ((D3DTRIANGLE*)ptr)+1;\
1337 U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1338 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1339 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1340 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1341 ptr = ((D3DTRIANGLE*)(ptr))+1;\
1344 static HRESULT CALLBACK TextureFormatEnumCallback(DDSURFACEDESC *lpDDSD, void *lpContext)
1346 if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1347 *(BOOL*)lpContext = TRUE;
1350 return DDENUMRET_OK;
1353 static void D3D1_TextureMapBlendTest(void)
1357 D3DEXECUTEBUFFERDESC exdesc;
1358 D3DEXECUTEDATA exdata;
1360 RECT rect = { 0, 0, 64, 128 };
1361 DWORD color, red, blue, green;
1362 void *exe_buffer_ptr;
1364 D3DTEXTUREHANDLE htex;
1366 IDirectDrawSurface *TexSurface = NULL;
1367 IDirect3DTexture *Texture = NULL;
1368 IDirectDrawPalette *Palette = NULL;
1369 PALETTEENTRY table1[256];
1370 BOOL p8_textures_supported = FALSE;
1380 {0.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1381 {640.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1382 {640.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1383 {0.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1384 {0.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1385 {640.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1386 {640.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1387 {0.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1390 {0.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1391 {640.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1392 {640.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1393 {0.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1394 {0.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1395 {640.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1396 {640.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1397 {0.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1400 /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1401 memset (&ddsd, 0, sizeof (ddsd));
1402 ddsd.dwSize = sizeof (ddsd);
1403 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1404 ddsd.dwHeight = 128;
1406 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1407 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1408 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1409 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1410 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1411 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1412 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1413 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1414 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1415 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1417 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1421 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1423 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1425 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1429 memset(&ddbltfx, 0, sizeof(ddbltfx));
1430 ddbltfx.dwSize = sizeof(ddbltfx);
1431 U5(ddbltfx).dwFillColor = 0;
1432 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1433 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1435 U5(ddbltfx).dwFillColor = 0xff0000ff;
1436 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1437 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1438 U5(ddbltfx).dwFillColor = 0x800000ff;
1439 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1440 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1442 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1443 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1444 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1445 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1447 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1451 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1453 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1455 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1457 EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1458 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, exe_buffer_ptr);
1459 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE, FALSE, exe_buffer_ptr);
1460 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE, FALSE, exe_buffer_ptr);
1461 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE, FALSE, exe_buffer_ptr);
1462 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_NEAREST, exe_buffer_ptr);
1463 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_NEAREST, exe_buffer_ptr);
1464 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE , D3DFILL_SOLID, exe_buffer_ptr);
1465 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA, exe_buffer_ptr);
1466 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA, exe_buffer_ptr);
1467 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1468 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, exe_buffer_ptr);
1469 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1470 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1471 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1473 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1474 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1476 EXEBUF_END(exe_buffer_ptr);
1478 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1480 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1482 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1485 memset(&exdata, 0, sizeof(exdata));
1486 exdata.dwSize = sizeof(exdata);
1487 exdata.dwVertexCount = 8;
1488 exdata.dwInstructionOffset = sizeof(test1_quads);
1489 exdata.dwInstructionLength = exe_length;
1490 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1491 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1493 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1494 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1496 if (SUCCEEDED(hr)) {
1497 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1498 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1499 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1500 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1503 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1504 red = (color & 0x00ff0000) >> 16;
1505 green = (color & 0x0000ff00) >> 8;
1506 blue = (color & 0x000000ff);
1507 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1509 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1510 red = (color & 0x00ff0000) >> 16;
1511 green = (color & 0x0000ff00) >> 8;
1512 blue = (color & 0x000000ff);
1513 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1515 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1516 red = (color & 0x00ff0000) >> 16;
1517 green = (color & 0x0000ff00) >> 8;
1518 blue = (color & 0x000000ff);
1519 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1521 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1522 red = (color & 0x00ff0000) >> 16;
1523 green = (color & 0x0000ff00) >> 8;
1524 blue = (color & 0x000000ff);
1525 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1527 /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1528 if(Texture) IDirect3DTexture_Release(Texture);
1530 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1533 memset (&ddsd, 0, sizeof (ddsd));
1534 ddsd.dwSize = sizeof (ddsd);
1535 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1536 ddsd.dwHeight = 128;
1538 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1539 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1540 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1541 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1542 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1543 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1544 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1546 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1547 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1549 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1553 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1555 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1557 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1561 memset(&ddbltfx, 0, sizeof(ddbltfx));
1562 ddbltfx.dwSize = sizeof(ddbltfx);
1563 U5(ddbltfx).dwFillColor = 0;
1564 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1565 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1567 U5(ddbltfx).dwFillColor = 0xff0000ff;
1568 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1569 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1570 U5(ddbltfx).dwFillColor = 0x800000ff;
1571 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1572 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1574 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1575 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1576 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1577 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1579 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1583 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1585 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1587 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1589 EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1590 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1591 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1592 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1594 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1595 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1597 EXEBUF_END(exe_buffer_ptr);
1599 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1601 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1603 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1606 memset(&exdata, 0, sizeof(exdata));
1607 exdata.dwSize = sizeof(exdata);
1608 exdata.dwVertexCount = 8;
1609 exdata.dwInstructionOffset = sizeof(test1_quads);
1610 exdata.dwInstructionLength = exe_length;
1611 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1612 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1614 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1615 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1617 if (SUCCEEDED(hr)) {
1618 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1619 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1620 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1621 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1624 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1625 red = (color & 0x00ff0000) >> 16;
1626 green = (color & 0x0000ff00) >> 8;
1627 blue = (color & 0x000000ff);
1628 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1630 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1631 red = (color & 0x00ff0000) >> 16;
1632 green = (color & 0x0000ff00) >> 8;
1633 blue = (color & 0x000000ff);
1634 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1636 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1637 red = (color & 0x00ff0000) >> 16;
1638 green = (color & 0x0000ff00) >> 8;
1639 blue = (color & 0x000000ff);
1640 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1642 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1643 red = (color & 0x00ff0000) >> 16;
1644 green = (color & 0x0000ff00) >> 8;
1645 blue = (color & 0x000000ff);
1646 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1648 /* 3) Test RGB - should multiply color components from diffuse color and texture */
1649 if(Texture) IDirect3DTexture_Release(Texture);
1651 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1654 memset (&ddsd, 0, sizeof (ddsd));
1655 ddsd.dwSize = sizeof (ddsd);
1656 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1657 ddsd.dwHeight = 128;
1659 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1660 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1661 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1662 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1663 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1664 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1665 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1666 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1667 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1668 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1670 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1674 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1676 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1678 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1682 memset(&ddbltfx, 0, sizeof(ddbltfx));
1683 ddbltfx.dwSize = sizeof(ddbltfx);
1684 U5(ddbltfx).dwFillColor = 0;
1685 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1686 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1688 U5(ddbltfx).dwFillColor = 0x00ffffff;
1689 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1690 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1691 U5(ddbltfx).dwFillColor = 0x00ffff80;
1692 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1693 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1695 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1696 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1697 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1698 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1700 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1704 memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1706 exe_buffer_ptr = sizeof(test2_quads) + (char*)exdesc.lpData;
1708 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1710 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1711 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1712 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1713 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1714 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1716 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1717 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1719 EXEBUF_END(exe_buffer_ptr);
1721 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test2_quads);
1723 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1725 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1728 memset(&exdata, 0, sizeof(exdata));
1729 exdata.dwSize = sizeof(exdata);
1730 exdata.dwVertexCount = 8;
1731 exdata.dwInstructionOffset = sizeof(test2_quads);
1732 exdata.dwInstructionLength = exe_length;
1733 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1734 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1736 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1737 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1739 if (SUCCEEDED(hr)) {
1740 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1741 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1742 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1743 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1746 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1747 red = (color & 0x00ff0000) >> 16;
1748 green = (color & 0x0000ff00) >> 8;
1749 blue = (color & 0x000000ff);
1750 ok(red == 0xff && green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1752 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1753 red = (color & 0x00ff0000) >> 16;
1754 green = (color & 0x0000ff00) >> 8;
1755 blue = (color & 0x000000ff);
1756 ok(red == 0xff && green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1758 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1759 red = (color & 0x00ff0000) >> 16;
1760 green = (color & 0x0000ff00) >> 8;
1761 blue = (color & 0x000000ff);
1762 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1764 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1765 red = (color & 0x00ff0000) >> 16;
1766 green = (color & 0x0000ff00) >> 8;
1767 blue = (color & 0x000000ff);
1768 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1770 /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1771 if(Texture) IDirect3DTexture_Release(Texture);
1773 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1776 memset (&ddsd, 0, sizeof (ddsd));
1777 ddsd.dwSize = sizeof (ddsd);
1778 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1779 ddsd.dwHeight = 128;
1781 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1782 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1783 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1784 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
1785 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xf800;
1786 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07e0;
1787 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001f;
1789 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1790 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1792 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1796 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1798 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1800 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1804 memset(&ddbltfx, 0, sizeof(ddbltfx));
1805 ddbltfx.dwSize = sizeof(ddbltfx);
1806 U5(ddbltfx).dwFillColor = 0;
1807 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1808 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1809 U5(ddbltfx).dwFillColor = 0xf800;
1810 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1811 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1812 U5(ddbltfx).dwFillColor = 0x001f;
1813 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1814 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1816 clrKey.dwColorSpaceLowValue = 0x001f;
1817 clrKey.dwColorSpaceHighValue = 0x001f;
1818 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1819 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1821 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1822 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1823 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1824 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1826 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1830 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1832 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1834 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1836 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1837 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1838 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1839 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1840 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1842 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1843 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1845 EXEBUF_END(exe_buffer_ptr);
1847 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1849 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1851 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1854 memset(&exdata, 0, sizeof(exdata));
1855 exdata.dwSize = sizeof(exdata);
1856 exdata.dwVertexCount = 8;
1857 exdata.dwInstructionOffset = sizeof(test1_quads);
1858 exdata.dwInstructionLength = exe_length;
1859 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1860 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1862 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1863 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1865 if (SUCCEEDED(hr)) {
1866 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1867 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1868 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1869 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1872 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1873 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1875 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1876 red = (color & 0x00ff0000) >> 16;
1877 green = (color & 0x0000ff00) >> 8;
1878 blue = (color & 0x000000ff);
1879 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1881 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1882 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1884 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1885 red = (color & 0x00ff0000) >> 16;
1886 green = (color & 0x0000ff00) >> 8;
1887 blue = (color & 0x000000ff);
1888 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1890 /* 5) Test alpha again, now with color keyed P8 texture */
1891 if(Texture) IDirect3DTexture_Release(Texture);
1893 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1896 hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1897 &p8_textures_supported);
1898 ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1900 if (!p8_textures_supported) {
1901 skip("device has no P8 texture support, skipping test\n");
1903 memset (&ddsd, 0, sizeof (ddsd));
1904 ddsd.dwSize = sizeof (ddsd);
1905 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1906 ddsd.dwHeight = 128;
1908 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1909 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1910 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1911 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1913 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1914 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1916 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1920 memset(table1, 0, sizeof(table1));
1921 table1[0].peBlue = 0xff;
1922 table1[1].peRed = 0xff;
1924 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1925 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1927 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1931 hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1932 ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1934 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1936 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1938 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1942 memset(&ddbltfx, 0, sizeof(ddbltfx));
1943 ddbltfx.dwSize = sizeof(ddbltfx);
1944 U5(ddbltfx).dwFillColor = 0;
1945 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1946 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1947 U5(ddbltfx).dwFillColor = 0;
1948 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1949 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1950 U5(ddbltfx).dwFillColor = 1;
1951 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1952 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1954 clrKey.dwColorSpaceLowValue = 1;
1955 clrKey.dwColorSpaceHighValue = 1;
1956 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1957 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1959 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1960 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1961 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1962 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1964 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1968 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1970 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1972 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1974 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1975 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1976 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1977 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1978 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1980 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1981 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1983 EXEBUF_END(exe_buffer_ptr);
1985 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1987 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1989 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1992 memset(&exdata, 0, sizeof(exdata));
1993 exdata.dwSize = sizeof(exdata);
1994 exdata.dwVertexCount = 8;
1995 exdata.dwInstructionOffset = sizeof(test1_quads);
1996 exdata.dwInstructionLength = exe_length;
1997 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1998 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
2000 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2001 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
2003 if (SUCCEEDED(hr)) {
2004 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
2005 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
2006 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2007 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
2010 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2011 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2013 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
2014 red = (color & 0x00ff0000) >> 16;
2015 green = (color & 0x0000ff00) >> 8;
2016 blue = (color & 0x000000ff);
2017 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
2019 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
2020 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2022 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
2023 red = (color & 0x00ff0000) >> 16;
2024 green = (color & 0x0000ff00) >> 8;
2025 blue = (color & 0x000000ff);
2026 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
2031 if (Palette) IDirectDrawPalette_Release(Palette);
2032 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
2033 if (Texture) IDirect3DTexture_Release(Texture);
2036 static void D3D1_ViewportClearTest(void)
2039 IDirect3DMaterial *bgMaterial = NULL;
2041 D3DMATERIALHANDLE hMat;
2042 D3DVIEWPORT vp_data;
2043 IDirect3DViewport *Viewport2 = NULL;
2044 DWORD color, red, green, blue;
2046 hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
2047 ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
2052 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
2053 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
2058 hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
2059 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
2060 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
2061 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
2062 vp_data.dwSize = sizeof(vp_data);
2065 vp_data.dwWidth = 100;
2066 vp_data.dwHeight = 100;
2067 vp_data.dvScaleX = 1;
2068 vp_data.dvScaleY = 1;
2069 vp_data.dvMaxX = 100;
2070 vp_data.dvMaxY = 100;
2073 hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
2074 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
2076 memset(&mat, 0, sizeof(mat));
2077 mat.dwSize = sizeof(mat);
2078 U1(U(mat).diffuse).r = 1.0f;
2079 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2080 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2082 hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
2083 ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
2085 hr = IDirect3DViewport_SetBackground(Viewport, hMat);
2086 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2087 hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
2088 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2090 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2091 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
2093 if (SUCCEEDED(hr)) {
2096 U1(rect).x1 = U2(rect).y1 = 0;
2100 hr = IDirect3DViewport_Clear(Viewport, 1, &rect, D3DCLEAR_TARGET);
2101 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2103 memset(&mat, 0, sizeof(mat));
2104 mat.dwSize = sizeof(mat);
2105 U3(U(mat).diffuse).b = 1.0f;
2106 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2107 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2109 hr = IDirect3DViewport_Clear(Viewport2, 1, &rect, D3DCLEAR_TARGET);
2110 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2112 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2113 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
2116 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2117 red = (color & 0x00ff0000) >> 16;
2118 green = (color & 0x0000ff00) >> 8;
2119 blue = (color & 0x000000ff);
2120 ok((red == 0xff && green == 0 && blue == 0) ||
2121 broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
2122 "Got color %08x, expected 00ff0000\n", color);
2124 color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
2125 red = (color & 0x00ff0000) >> 16;
2126 green = (color & 0x0000ff00) >> 8;
2127 blue = (color & 0x000000ff);
2128 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
2132 if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
2133 if (Viewport2) IDirect3DViewport_Release(Viewport2);
2136 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
2140 DDSURFACEDESC2 ddsd;
2141 RECT rectToLock = {x, y, x+1, y+1};
2142 IDirectDrawSurface4 *surf = NULL;
2144 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
2145 * to an offscreen surface and lock it instead of the front buffer
2147 memset(&ddsd, 0, sizeof(ddsd));
2148 ddsd.dwSize = sizeof(ddsd);
2149 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2150 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
2152 ddsd.dwHeight = 480;
2153 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
2154 hr = IDirectDraw4_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
2155 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2158 trace("cannot create helper surface\n");
2162 memset(&ddsd, 0, sizeof(ddsd));
2163 ddsd.dwSize = sizeof(ddsd);
2164 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2166 hr = IDirectDrawSurface4_BltFast(surf, 0, 0, Surface, NULL, 0);
2167 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
2170 trace("Cannot blit\n");
2175 hr = IDirectDrawSurface4_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
2178 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
2183 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
2184 * really important for these tests
2186 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
2187 hr = IDirectDrawSurface4_Unlock(surf, NULL);
2190 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
2194 IDirectDrawSurface4_Release(surf);
2198 static void D3D3_ViewportClearTest(void)
2201 IDirectDraw *DirectDraw1 = NULL;
2202 IDirectDraw4 *DirectDraw4 = NULL;
2203 IDirectDrawSurface4 *Primary = NULL;
2204 IDirect3D3 *Direct3D3 = NULL;
2205 IDirect3DViewport3 *Viewport3 = NULL;
2206 IDirect3DViewport3 *SmallViewport3 = NULL;
2207 IDirect3DDevice3 *Direct3DDevice3 = NULL;
2209 DDSURFACEDESC2 ddsd;
2210 D3DVIEWPORT2 vp_data;
2211 DWORD color, red, green, blue;
2213 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
2214 0.0f, 1.0f, 0.0f, 0.0f,
2215 0.0f, 0.0f, 1.0f, 0.0f,
2216 0.0f, 0.0f, 0.0f, 1.0f };
2217 struct vertex quad[] =
2219 {-1.0f, -1.0f, 0.1f, 0xffffffff},
2220 {-1.0f, 1.0f, 0.1f, 0xffffffff},
2221 { 1.0f, 1.0f, 0.1f, 0xffffffff},
2222 { 1.0f, -1.0f, 0.1f, 0xffffffff},
2225 WORD Indices[] = {0, 1, 2, 2, 3, 0};
2226 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
2228 wc.lpfnWndProc = DefWindowProc;
2229 wc.lpszClassName = "D3D3_ViewportClearTest_wc";
2231 window = CreateWindow("D3D3_ViewportClearTest_wc", "D3D3_ViewportClearTest",
2232 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2234 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2235 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2236 if(FAILED(hr)) goto out;
2238 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2239 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2240 if(FAILED(hr)) goto out;
2242 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2244 /* 24 bit is fine too */
2245 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2247 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2248 if (FAILED(hr)) goto out;
2250 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void**)&DirectDraw4);
2251 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
2252 if(FAILED(hr)) goto out;
2254 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2255 ddsd.dwSize = sizeof(DDSURFACEDESC2);
2256 ddsd.dwFlags = DDSD_CAPS;
2257 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
2259 hr = IDirectDraw_CreateSurface(DirectDraw4, &ddsd, &Primary, NULL);
2260 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2261 if(FAILED(hr)) goto out;
2263 hr = IDirectDraw4_QueryInterface(DirectDraw4, &IID_IDirect3D3, (void**)&Direct3D3);
2264 ok(hr==DD_OK, "IDirectDraw4_QueryInterface returned: %08x\n", hr);
2265 if(FAILED(hr)) goto out;
2267 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DHALDevice, Primary, &Direct3DDevice3, NULL);
2269 trace("Creating a HAL device failed, trying Ref\n");
2270 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DRefDevice, Primary, &Direct3DDevice3, NULL);
2272 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
2273 if(FAILED(hr)) goto out;
2275 hr = IDirect3D3_CreateViewport(Direct3D3, &Viewport3, NULL);
2276 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2277 if(FAILED(hr)) goto out;
2279 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, Viewport3);
2280 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2282 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2283 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2284 vp_data.dwWidth = 640;
2285 vp_data.dwHeight = 480;
2286 vp_data.dvClipX = -1.0f;
2287 vp_data.dvClipWidth = 2.0f;
2288 vp_data.dvClipY = 1.0f;
2289 vp_data.dvClipHeight = 2.0f;
2290 vp_data.dvMaxZ = 1.0f;
2291 hr = IDirect3DViewport3_SetViewport2(Viewport3, &vp_data);
2292 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2294 hr = IDirect3D3_CreateViewport(Direct3D3, &SmallViewport3, NULL);
2295 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2296 if(FAILED(hr)) goto out;
2298 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, SmallViewport3);
2299 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2301 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2302 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2305 vp_data.dwWidth = 100;
2306 vp_data.dwHeight = 100;
2307 vp_data.dvClipX = -1.0f;
2308 vp_data.dvClipWidth = 2.0f;
2309 vp_data.dvClipY = 1.0f;
2310 vp_data.dvClipHeight = 2.0f;
2311 vp_data.dvMaxZ = 1.0f;
2312 hr = IDirect3DViewport3_SetViewport2(SmallViewport3, &vp_data);
2313 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2315 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2316 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2318 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
2319 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2320 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
2321 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2322 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
2323 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2324 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CLIPPING, FALSE);
2325 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2326 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ZENABLE, FALSE);
2327 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2328 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_FOGENABLE, FALSE);
2329 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2330 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_STENCILENABLE, FALSE);
2331 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2332 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
2333 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2334 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
2335 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2336 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
2337 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState failed with %08x\n", hr);
2338 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
2339 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2341 if (SUCCEEDED(hr)) {
2342 U1(rect).x1 = U2(rect).y1 = 0;
2346 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x00ff00, 0.0f, 0);
2347 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2349 hr = IDirect3DViewport3_Clear2(SmallViewport3, 1, &rect, D3DCLEAR_TARGET, 0xff0000, 0.0f, 0);
2350 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2352 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2353 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2356 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2357 red = (color & 0x00ff0000) >> 16;
2358 green = (color & 0x0000ff00) >> 8;
2359 blue = (color & 0x000000ff);
2360 ok(red == 0 && green == 0xff && blue == 0, "Got color %08x, expected 0000ff00\n", color);
2362 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2363 red = (color & 0x00ff0000) >> 16;
2364 green = (color & 0x0000ff00) >> 8;
2365 blue = (color & 0x000000ff);
2366 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000\n", color);
2368 /* Test that clearing viewport doesn't interfere with rendering to previously active viewport. */
2369 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2370 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2372 if (SUCCEEDED(hr)) {
2373 hr = IDirect3DDevice3_SetCurrentViewport(Direct3DDevice3, SmallViewport3);
2374 ok(hr == D3D_OK, "IDirect3DDevice3_SetCurrentViewport failed with %08x\n", hr);
2376 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x000000, 0.0f, 0);
2377 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2379 hr = IDirect3DDevice3_DrawIndexedPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf, quad, 4 /* NumVerts */,
2380 Indices, 6 /* Indexcount */, 0 /* flags */);
2381 ok(hr == D3D_OK, "IDirect3DDevice3_DrawIndexedPrimitive failed with %08x\n", hr);
2383 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2384 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2387 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2388 red = (color & 0x00ff0000) >> 16;
2389 green = (color & 0x0000ff00) >> 8;
2390 blue = (color & 0x000000ff);
2391 ok(red == 0 && green == 0 && blue == 0, "Got color %08x, expected 00000000\n", color);
2393 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2394 red = (color & 0x00ff0000) >> 16;
2395 green = (color & 0x0000ff00) >> 8;
2396 blue = (color & 0x000000ff);
2397 ok(red == 0xff && green == 0xff && blue == 0xff, "Got color %08x, expected 00ffffff\n", color);
2401 if (SmallViewport3) IDirect3DViewport3_Release(SmallViewport3);
2402 if (Viewport3) IDirect3DViewport3_Release(Viewport3);
2403 if (Direct3DDevice3) IDirect3DDevice3_Release(Direct3DDevice3);
2404 if (Direct3D3) IDirect3D3_Release(Direct3D3);
2405 if (Primary) IDirectDrawSurface4_Release(Primary);
2406 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
2407 if (DirectDraw4) IDirectDraw4_Release(DirectDraw4);
2408 if(window) DestroyWindow(window);
2411 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
2418 memset(&ddsd, 0, sizeof(ddsd));
2419 ddsd.dwSize = sizeof(ddsd);
2421 hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
2422 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2424 p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2426 for (i = 0; i < h; i++) {
2427 for (i1 = 0; i1 < w; i1++) {
2430 p += U1(ddsd).lPitch;
2433 hr = IDirectDrawSurface_Unlock(dest, NULL);
2434 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2437 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
2439 COLORREF clr = CLR_INVALID;
2443 hr = IDirectDrawSurface_GetDC(Surface, &hdc);
2444 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2446 if (SUCCEEDED(hr)) {
2447 clr = GetPixel(hdc, x, y);
2449 hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
2450 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2456 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
2460 for (i = 0; i < 256; i++) {
2461 if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
2462 table1[i].peBlue != table2[i].rgbBlue) return FALSE;
2468 static void p8_primary_test(void)
2470 /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
2474 PALETTEENTRY entries[256];
2475 RGBQUAD coltable[256];
2477 IDirectDrawPalette *ddprimpal = NULL;
2478 IDirectDrawSurface *offscreen = NULL;
2484 unsigned differences;
2486 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
2487 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
2489 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2494 wc.lpfnWndProc = DefWindowProc;
2495 wc.lpszClassName = "p8_primary_test_wc";
2497 window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2499 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2500 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2505 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
2506 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2511 memset(&ddsd, 0, sizeof(ddsd));
2512 ddsd.dwSize = sizeof(ddsd);
2513 ddsd.dwFlags = DDSD_CAPS;
2514 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2515 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
2516 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
2521 memset(entries, 0, sizeof(entries));
2522 entries[0].peRed = 0xff;
2523 entries[1].peGreen = 0xff;
2524 entries[2].peBlue = 0xff;
2526 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
2527 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2529 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
2533 hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
2534 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2536 p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
2538 color = getPixelColor_GDI(Surface1, 10, 10);
2539 ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
2540 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2541 GetRValue(color), GetGValue(color), GetBValue(color));
2543 memset(&ddbltfx, 0, sizeof(ddbltfx));
2544 ddbltfx.dwSize = sizeof(ddbltfx);
2545 U5(ddbltfx).dwFillColor = 0;
2546 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2547 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2549 color = getPixelColor_GDI(Surface1, 10, 10);
2550 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
2551 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
2552 GetRValue(color), GetGValue(color), GetBValue(color));
2554 memset(&ddbltfx, 0, sizeof(ddbltfx));
2555 ddbltfx.dwSize = sizeof(ddbltfx);
2556 U5(ddbltfx).dwFillColor = 1;
2557 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2558 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2560 color = getPixelColor_GDI(Surface1, 10, 10);
2561 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2562 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2563 GetRValue(color), GetGValue(color), GetBValue(color));
2565 memset (&ddsd, 0, sizeof (ddsd));
2566 ddsd.dwSize = sizeof (ddsd);
2567 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2570 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
2571 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2572 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2573 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2574 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2576 broken(hr == DDERR_INVALIDPIXELFORMAT) || /* VMware */
2577 broken(hr == DDERR_NODIRECTDRAWHW), /* VMware */
2578 "IDirectDraw_CreateSurface returned %08x\n", hr);
2579 if (FAILED(hr)) goto out;
2581 memset(entries, 0, sizeof(entries));
2582 for (i = 0; i < 256; i++) {
2583 entries[i].peBlue = i;
2585 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2586 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2588 hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
2589 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2590 i = GetDIBColorTable(hdc, 0, 256, coltable);
2591 ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
2592 hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
2593 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2595 ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
2597 p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 2);
2599 memset(entries, 0, sizeof(entries));
2600 entries[0].peRed = 0xff;
2601 entries[1].peGreen = 0xff;
2602 entries[2].peBlue = 0xff;
2603 entries[3].peRed = 0x80;
2604 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2605 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2607 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2608 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2610 color = getPixelColor_GDI(Surface1, 1, 1);
2611 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2612 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2613 GetRValue(color), GetGValue(color), GetBValue(color));
2615 /* Color keyed blit. */
2616 p8_surface_fill_rect(offscreen, 0, 0, 8, 8, 3);
2617 clrKey.dwColorSpaceLowValue = 3;
2618 clrKey.dwColorSpaceHighValue = 3;
2619 hr = IDirectDrawSurface_SetColorKey(offscreen, DDCKEY_SRCBLT, &clrKey);
2620 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
2622 hr = IDirectDrawSurface_BltFast(Surface1, 100, 100, offscreen, NULL, DDBLTFAST_SRCCOLORKEY);
2623 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2625 color = getPixelColor_GDI(Surface1, 105, 105);
2626 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2627 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2628 GetRValue(color), GetGValue(color), GetBValue(color));
2630 color = getPixelColor_GDI(Surface1, 112, 112);
2631 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2632 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2633 GetRValue(color), GetGValue(color), GetBValue(color));
2640 memset(&ddbltfx, 0, sizeof(ddbltfx));
2641 ddbltfx.dwSize = sizeof(ddbltfx);
2642 ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 2;
2643 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2644 DDBLT_WAIT | DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2645 ok(hr==DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned: %x\n", hr);
2646 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2647 DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2648 ok(hr==DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2650 color = getPixelColor_GDI(Surface1, 105, 205);
2651 ok(GetRValue(color) == 0x80 && GetGValue(color) == 0 && GetBValue(color) == 0,
2652 "got R %02X G %02X B %02X, expected R 80 G 00 B 00\n",
2653 GetRValue(color), GetGValue(color), GetBValue(color));
2655 color = getPixelColor_GDI(Surface1, 112, 212);
2656 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2657 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2658 GetRValue(color), GetGValue(color), GetBValue(color));
2660 /* Test blitting and locking patterns that are likely to trigger bugs in opengl renderer (p8
2661 surface conversion and uploading/downloading to/from opengl texture). Similar patterns (
2662 blitting front buffer areas to/from an offscreen surface mixed with locking) are used by C&C
2664 IDirectDrawSurface_Release(offscreen);
2666 memset (&ddsd, 0, sizeof (ddsd));
2667 ddsd.dwSize = sizeof (ddsd);
2668 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2670 ddsd.dwHeight = 480;
2671 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2672 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2673 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2674 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2675 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2676 ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
2678 if (FAILED(hr)) goto out;
2680 /* Test two times, first time front buffer has a palette and second time front buffer
2681 has no palette; the latter is somewhat contrived example, but an app could set
2682 front buffer palette later. */
2683 for (i2 = 0; i2 < 2; i2++) {
2685 hr = IDirectDrawSurface_SetPalette(Surface1, NULL);
2686 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2689 memset(&ddsd, 0, sizeof(ddsd));
2690 ddsd.dwSize = sizeof(ddsd);
2691 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2692 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2694 for (i = 0; i < 256; i++) {
2695 unsigned x = (i % 128) * 4;
2696 unsigned y = (i / 128) * 4;
2697 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2699 for (i1 = 0; i1 < 4; i1++) {
2700 p[0] = p[1] = p[2] = p[3] = i;
2701 p += U1(ddsd).lPitch;
2705 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2706 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2708 hr = IDirectDrawSurface_BltFast(offscreen, 0, 0, Surface1, NULL, 0);
2709 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2711 /* This ensures offscreen surface contents will be downloaded to system memory. */
2712 memset(&ddsd, 0, sizeof(ddsd));
2713 ddsd.dwSize = sizeof(ddsd);
2714 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2715 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2716 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2717 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2719 /* Offscreen surface data will have to be converted and uploaded to texture. */
2724 hr = IDirectDrawSurface_BltFast(offscreen, 600, 400, Surface1, &rect, 0);
2725 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2727 /* This ensures offscreen surface contents will be downloaded to system memory. */
2728 memset(&ddsd, 0, sizeof(ddsd));
2729 ddsd.dwSize = sizeof(ddsd);
2730 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2731 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2732 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2733 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2735 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2736 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2738 memset(&ddsd, 0, sizeof(ddsd));
2739 ddsd.dwSize = sizeof(ddsd);
2740 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2741 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2745 for (i = 0; i < 256; i++) {
2746 unsigned x = (i % 128) * 4 + 1;
2747 unsigned y = (i / 128) * 4 + 1;
2748 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2750 if (*p != i) differences++;
2753 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2754 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2756 ok(differences == 0, i2 == 0 ? "Pass 1. Unexpected front buffer contents after blit (%u differences)\n" :
2757 "Pass 2 (with NULL front buffer palette). Unexpected front buffer contents after blit (%u differences)\n",
2763 if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
2764 if(offscreen) IDirectDrawSurface_Release(offscreen);
2765 if(Surface1) IDirectDrawSurface_Release(Surface1);
2766 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
2767 if(window) DestroyWindow(window);
2770 static void cubemap_test(IDirect3DDevice7 *device)
2773 IDirectDraw7 *ddraw;
2774 IDirectDrawSurface7 *cubemap, *surface;
2775 D3DDEVICEDESC7 d3dcaps;
2778 DDSURFACEDESC2 ddsd;
2781 static float quad[] = {
2782 -1.0, -1.0, 0.1, 1.0, 0.0, 0.0, /* Lower left */
2783 0.0, -1.0, 0.1, 1.0, 0.0, 0.0,
2784 -1.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2785 0.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2787 0.0, -1.0, 0.1, 0.0, 1.0, 0.0, /* Lower right */
2788 1.0, -1.0, 0.1, 0.0, 1.0, 0.0,
2789 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2790 1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2792 0.0, 0.0, 0.1, 0.0, 0.0, 1.0, /* upper right */
2793 1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
2794 0.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2795 1.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2797 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, /* Upper left */
2798 0.0, 0.0, 0.1, -1.0, 0.0, 0.0,
2799 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2800 0.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2803 memset(&DDBltFx, 0, sizeof(DDBltFx));
2804 DDBltFx.dwSize = sizeof(DDBltFx);
2806 memset(&d3dcaps, 0, sizeof(d3dcaps));
2807 hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
2808 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2809 if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2811 skip("No cubemap support\n");
2815 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2816 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
2818 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2819 ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
2820 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
2821 ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
2822 IDirect3D7_Release(d3d);
2825 memset(&ddsd, 0, sizeof(ddsd));
2826 ddsd.dwSize = sizeof(ddsd);
2827 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2828 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2831 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2832 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
2833 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2834 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2835 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2836 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2837 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2839 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
2840 ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
2841 IDirectDraw7_Release(ddraw);
2844 U5(DDBltFx).dwFillColor = 0x00ff0000;
2845 hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2846 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2848 memset(&caps, 0, sizeof(caps));
2849 caps.dwCaps = DDSCAPS_TEXTURE;
2850 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
2851 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2852 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2853 U5(DDBltFx).dwFillColor = 0x0000ffff;
2854 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2855 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2857 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
2858 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2859 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2860 U5(DDBltFx).dwFillColor = 0x0000ff00;
2861 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2862 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2864 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
2865 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2866 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2867 U5(DDBltFx).dwFillColor = 0x000000ff;
2868 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2869 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2871 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2872 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2873 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2874 U5(DDBltFx).dwFillColor = 0x00ffff00;
2875 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2876 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2878 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2879 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2880 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2881 U5(DDBltFx).dwFillColor = 0x00ff00ff;
2882 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2883 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2885 hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2886 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2887 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2888 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2889 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2890 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2892 hr = IDirect3DDevice7_BeginScene(device);
2893 ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2896 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2897 if (hr == DDERR_UNSUPPORTED || hr == DDERR_NODIRECTDRAWHW)
2900 win_skip("IDirect3DDevice7_DrawPrimitive is not completely implemented, colors won't be tested\n");
2901 hr = IDirect3DDevice7_EndScene(device);
2902 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2905 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2906 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
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 + 8 * 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 + 12* 6, 4, 0);
2911 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2913 hr = IDirect3DDevice7_EndScene(device);
2914 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2916 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2917 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2919 color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2920 ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2921 color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2922 ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2923 color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2924 ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2925 color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2926 ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2929 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2930 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2931 IDirectDrawSurface7_Release(cubemap);
2934 /* This test tests depth clamping / clipping behaviour:
2935 * - With software vertex processing, depth values are clamped to the
2936 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2937 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2938 * same as regular vertices here.
2939 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2940 * Normal vertices are always clipped. Pretransformed vertices are
2941 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2942 * - The viewport's MinZ/MaxZ is irrelevant for this.
2944 static void depth_clamp_test(IDirect3DDevice7 *device)
2946 struct tvertex quad1[] =
2948 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2949 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2950 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2951 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2953 struct tvertex quad2[] =
2955 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2956 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2957 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2958 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2960 struct tvertex quad3[] =
2962 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2963 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2964 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2965 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2967 struct tvertex quad4[] =
2969 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2970 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2971 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2972 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2974 struct vertex quad5[] =
2976 { -0.5f, 0.5f, 10.0f, 0xff14f914},
2977 { 0.5f, 0.5f, 10.0f, 0xff14f914},
2978 { -0.5f, -0.5f, 10.0f, 0xff14f914},
2979 { 0.5f, -0.5f, 10.0f, 0xff14f914},
2981 struct vertex quad6[] =
2983 { -1.0f, 0.5f, 10.0f, 0xfff91414},
2984 { 1.0f, 0.5f, 10.0f, 0xfff91414},
2985 { -1.0f, 0.25f, 10.0f, 0xfff91414},
2986 { 1.0f, 0.25f, 10.0f, 0xfff91414},
3000 hr = IDirect3DDevice7_SetViewport(device, &vp);
3001 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3003 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3004 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3006 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3007 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3008 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
3009 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3010 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZWRITEENABLE, TRUE);
3011 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3012 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
3013 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3015 hr = IDirect3DDevice7_BeginScene(device);
3016 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3018 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
3019 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3020 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad2, 4, 0);
3021 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3023 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3024 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3026 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad3, 4, 0);
3027 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3028 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad4, 4, 0);
3029 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3031 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3032 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3034 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad5, 4, 0);
3035 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3037 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3038 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3040 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad6, 4, 0);
3041 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3043 hr = IDirect3DDevice7_EndScene(device);
3044 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3046 color = getPixelColor(device, 75, 75);
3047 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3048 color = getPixelColor(device, 150, 150);
3049 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3050 color = getPixelColor(device, 320, 240);
3051 ok(color_match(color, 0x00002b7f, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3052 color = getPixelColor(device, 320, 330);
3053 ok(color_match(color, 0x00f9e814, 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);
3059 hr = IDirect3DDevice7_SetViewport(device, &vp);
3060 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3063 static void DX1_BackBufferFlipTest(void)
3066 IDirectDraw *DirectDraw1 = NULL;
3067 IDirectDrawSurface *Primary = NULL;
3068 IDirectDrawSurface *Backbuffer = NULL;
3073 const DWORD white = 0xffffff;
3074 const DWORD red = 0xff0000;
3075 BOOL attached = FALSE;
3077 wc.lpfnWndProc = DefWindowProc;
3078 wc.lpszClassName = "DX1_BackBufferFlipTest_wc";
3080 window = CreateWindow("DX1_BackBufferFlipTest_wc", "DX1_BackBufferFlipTest",
3081 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3083 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
3084 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
3085 if(FAILED(hr)) goto out;
3087 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3088 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
3089 if(FAILED(hr)) goto out;
3091 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
3093 /* 24 bit is fine too */
3094 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
3096 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
3101 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3102 ddsd.dwSize = sizeof(DDSURFACEDESC);
3103 ddsd.dwFlags = DDSD_CAPS;
3104 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3106 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Primary, NULL);
3107 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3109 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3110 ddsd.dwSize = sizeof(DDSURFACEDESC);
3111 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3112 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3114 ddsd.dwHeight = 480;
3115 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3116 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3117 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
3118 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
3119 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
3120 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
3122 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Backbuffer, NULL);
3123 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3124 if(FAILED(hr)) goto out;
3126 hr = IDirectDrawSurface_AddAttachedSurface(Primary, Backbuffer);
3127 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3128 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3129 if (FAILED(hr)) goto out;
3133 memset(&ddbltfx, 0, sizeof(ddbltfx));
3134 ddbltfx.dwSize = sizeof(ddbltfx);
3135 U5(ddbltfx).dwFillColor = red;
3136 hr = IDirectDrawSurface_Blt(Backbuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3137 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3139 U5(ddbltfx).dwFillColor = white;
3140 hr = IDirectDrawSurface_Blt(Primary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3141 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3144 color = getPixelColor_GDI(Primary, 5, 5);
3145 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF,
3146 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3147 GetRValue(color), GetGValue(color), GetBValue(color));
3149 color = getPixelColor_GDI(Backbuffer, 5, 5);
3150 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3151 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3152 GetRValue(color), GetGValue(color), GetBValue(color));
3154 hr = IDirectDrawSurface_Flip(Primary, NULL, DDFLIP_WAIT);
3155 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3159 color = getPixelColor_GDI(Primary, 5, 5);
3160 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3161 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3162 GetRValue(color), GetGValue(color), GetBValue(color));
3164 color = getPixelColor_GDI(Backbuffer, 5, 5);
3165 ok((GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF) ||
3166 broken(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0), /* broken driver */
3167 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3168 GetRValue(color), GetGValue(color), GetBValue(color));
3176 IDirectDrawSurface_DeleteAttachedSurface(Primary, 0, Backbuffer);
3177 IDirectDrawSurface_Release(Backbuffer);
3179 if (Primary) IDirectDrawSurface_Release(Primary);
3180 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
3181 if (window) DestroyWindow(window);
3188 if(!createObjects())
3190 skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
3194 /* Check for the reliability of the returned data */
3195 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3198 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3202 color = getPixelColor(Direct3DDevice, 1, 1);
3203 if(color !=0x00ff0000)
3205 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3209 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3212 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3216 color = getPixelColor(Direct3DDevice, 639, 479);
3217 if(color != 0x0000ddee)
3219 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3223 /* Now run the tests */
3224 blt_test(Direct3DDevice);
3225 depth_clamp_test(Direct3DDevice);
3226 lighting_test(Direct3DDevice);
3227 clear_test(Direct3DDevice);
3228 fog_test(Direct3DDevice);
3229 offscreen_test(Direct3DDevice);
3230 alpha_test(Direct3DDevice);
3231 rhw_zero_test(Direct3DDevice);
3232 cubemap_test(Direct3DDevice);
3234 releaseObjects(); /* release DX7 interfaces to test D3D1 */
3236 if(!D3D1_createObjects()) {
3237 skip("Cannot initialize D3D1, skipping\n");
3240 D3D1_TextureMapBlendTest();
3241 D3D1_ViewportClearTest();
3243 D3D1_releaseObjects();
3245 D3D3_ViewportClearTest();
3247 DX1_BackBufferFlipTest();