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 */
23 #include "wine/test.h"
28 static IDirectDraw7 *DirectDraw;
29 static IDirectDrawSurface7 *Surface;
30 static IDirectDrawSurface7 *depth_buffer;
31 static IDirect3D7 *Direct3D;
32 static IDirect3DDevice7 *Direct3DDevice;
34 static IDirectDraw *DirectDraw1;
35 static IDirectDrawSurface *Surface1;
36 static IDirect3D *Direct3D1;
37 static IDirect3DDevice *Direct3DDevice1;
38 static IDirect3DExecuteBuffer *ExecuteBuffer;
39 static IDirect3DViewport *Viewport;
41 static BOOL refdevice = FALSE;
43 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
45 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
47 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
49 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
51 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 static HRESULT WINAPI enum_z_fmt(DDPIXELFORMAT *fmt, void *ctx)
59 DDPIXELFORMAT *zfmt = ctx;
61 if(U1(*fmt).dwZBufferBitDepth > U1(*zfmt).dwZBufferBitDepth)
68 static BOOL createObjects(void)
71 HMODULE hmod = GetModuleHandleA("ddraw.dll");
76 if(!hmod) return FALSE;
77 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
78 if(!pDirectDrawCreateEx) return FALSE;
80 hr = pDirectDrawCreateEx(NULL, (void **) &DirectDraw, &IID_IDirectDraw7, NULL);
81 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
82 if(!DirectDraw) goto err;
84 wc.lpfnWndProc = DefWindowProc;
85 wc.lpszClassName = "d3d7_test_wc";
87 window = CreateWindow("d3d7_test_wc", "d3d7_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
89 hr = IDirectDraw7_SetCooperativeLevel(DirectDraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
90 ok(hr == DD_OK, "IDirectDraw7_SetCooperativeLevel failed with %08x\n", hr);
91 if(FAILED(hr)) goto err;
92 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 32, 0, 0);
94 /* 24 bit is fine too */
95 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 24, 0, 0);
98 ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "IDirectDraw7_SetDisplayMode failed with %08x\n", hr);
100 /* use trace, the caller calls skip() */
101 trace("SetDisplayMode failed\n");
105 hr = IDirectDraw7_QueryInterface(DirectDraw, &IID_IDirect3D7, (void**) &Direct3D);
106 if (hr == E_NOINTERFACE) goto err;
107 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
109 /* DirectDraw Flipping behavior doesn't seem that well-defined. The reference rasterizer behaves differently
110 * than hardware implementations. Request single buffering, that seems to work everywhere
112 memset(&ddsd, 0, sizeof(ddsd));
113 ddsd.dwSize = sizeof(ddsd);
114 ddsd.dwFlags = DDSD_CAPS;
115 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
116 ddsd.dwBackBufferCount = 1;
117 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &Surface, NULL);
118 if(FAILED(hr)) goto err;
120 memset(&zfmt, 0, sizeof(zfmt));
121 hr = IDirect3D7_EnumZBufferFormats(Direct3D, &IID_IDirect3DTnLHalDevice, enum_z_fmt, &zfmt);
122 if (FAILED(hr)) goto err;
123 if (zfmt.dwSize == 0) goto err;
125 memset(&ddsd, 0, sizeof(ddsd));
126 ddsd.dwSize = sizeof(ddsd);
127 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
128 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
129 U4(ddsd).ddpfPixelFormat = zfmt;
132 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &depth_buffer, NULL);
133 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr);
134 if (FAILED(hr)) goto err;
136 hr = IDirectDrawSurface_AddAttachedSurface(Surface, depth_buffer);
137 ok(SUCCEEDED(hr), "AddAttachedSurface failed, hr %#x.\n", hr);
138 if (FAILED(hr)) goto err;
140 hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DTnLHalDevice, Surface, &Direct3DDevice);
141 if (FAILED(hr) || !Direct3DDevice) goto err;
145 if(DirectDraw) IDirectDraw7_Release(DirectDraw);
146 if (depth_buffer) IDirectDrawSurface7_Release(depth_buffer);
147 if(Surface) IDirectDrawSurface7_Release(Surface);
148 if(Direct3D) IDirect3D7_Release(Direct3D);
149 if(Direct3DDevice) IDirect3DDevice7_Release(Direct3DDevice);
150 if(window) DestroyWindow(window);
154 static void releaseObjects(void)
156 IDirect3DDevice7_Release(Direct3DDevice);
157 IDirect3D7_Release(Direct3D);
158 IDirectDrawSurface7_Release(depth_buffer);
159 IDirectDrawSurface7_Release(Surface);
160 IDirectDraw7_Release(DirectDraw);
161 DestroyWindow(window);
164 static DWORD getPixelColor(IDirect3DDevice7 *device, UINT x, UINT y)
169 RECT rectToLock = {x, y, x+1, y+1};
170 IDirectDrawSurface7 *surf = NULL;
172 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
173 * to an offscreen surface and lock it instead of the front buffer
175 memset(&ddsd, 0, sizeof(ddsd));
176 ddsd.dwSize = sizeof(ddsd);
177 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
178 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
181 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
182 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
183 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with %08x\n", hr);
186 trace("cannot create helper surface\n");
190 memset(&ddsd, 0, sizeof(ddsd));
191 ddsd.dwSize = sizeof(ddsd);
192 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
194 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
195 ok(hr == DD_OK, "IDirectDrawSurface7_BltFast returned %08x\n", hr);
198 trace("Cannot blit\n");
203 hr = IDirectDrawSurface7_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
206 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
211 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
212 * really important for these tests
214 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
215 hr = IDirectDrawSurface7_Unlock(surf, NULL);
218 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
222 IDirectDrawSurface7_Release(surf);
226 static void set_viewport_size(IDirect3DDevice7 *device)
228 D3DVIEWPORT7 vp = {0};
231 IDirectDrawSurface7 *target;
233 hr = IDirect3DDevice7_GetRenderTarget(device, &target);
234 ok(hr == D3D_OK, "IDirect3DDevice7_GetRenderTarget returned %08x\n", hr);
236 memset(&ddsd, 0, sizeof(ddsd));
237 ddsd.dwSize = sizeof(ddsd);
238 IDirectDrawSurface7_GetSurfaceDesc(target, &ddsd);
239 ok(hr == D3D_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
240 IDirectDrawSurface7_Release(target);
242 vp.dwWidth = ddsd.dwWidth;
243 vp.dwHeight = ddsd.dwHeight;
244 hr = IDirect3DDevice7_SetViewport(device, &vp);
245 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport returned %08x\n", hr);
268 static void lighting_test(IDirect3DDevice7 *device)
271 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
272 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
275 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
276 0.0f, 1.0f, 0.0f, 0.0f,
277 0.0f, 0.0f, 1.0f, 0.0f,
278 0.0f, 0.0f, 0.0f, 1.0f };
280 struct vertex unlitquad[] =
282 {-1.0f, -1.0f, 0.1f, 0xffff0000},
283 {-1.0f, 0.0f, 0.1f, 0xffff0000},
284 { 0.0f, 0.0f, 0.1f, 0xffff0000},
285 { 0.0f, -1.0f, 0.1f, 0xffff0000},
287 struct vertex litquad[] =
289 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
290 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
291 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
292 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
294 struct nvertex unlitnquad[] =
296 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
297 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
298 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
299 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
301 struct nvertex litnquad[] =
303 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
304 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
305 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
306 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
308 WORD Indices[] = {0, 1, 2, 2, 3, 0};
310 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
311 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
313 /* Setup some states that may cause issues */
314 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
315 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
316 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
317 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
318 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
319 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
320 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
321 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
322 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
323 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
324 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
325 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_STENCILENABLE, FALSE);
327 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
328 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
329 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
330 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
331 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
332 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
333 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed with %08x\n", hr);
335 hr = IDirect3DDevice7_BeginScene(device);
336 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
339 /* No lights are defined... That means, lit vertices should be entirely black */
340 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
341 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
342 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, unlitquad, 4 /* NumVerts */,
343 Indices, 6 /* Indexcount */, 0 /* flags */);
344 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
346 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
347 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
348 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, litquad, 4 /* NumVerts */,
349 Indices, 6 /* Indexcount */, 0 /* flags */);
350 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
352 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
353 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
354 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, unlitnquad, 4 /* NumVerts */,
355 Indices, 6 /* Indexcount */, 0 /* flags */);
356 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
358 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
359 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
360 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, litnquad, 4 /* NumVerts */,
361 Indices, 6 /* Indexcount */, 0 /* flags */);
362 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
364 IDirect3DDevice7_EndScene(device);
365 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
368 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
369 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
370 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
371 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
372 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
373 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
374 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
375 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
377 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
378 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
381 static void clear_test(IDirect3DDevice7 *device)
383 /* Tests the correctness of clearing parameters */
389 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
390 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
392 /* Positive x, negative y */
394 U2(rect[0]).y1 = 480;
395 U3(rect[0]).x2 = 320;
396 U4(rect[0]).y2 = 240;
398 /* Positive x, positive y */
401 U3(rect[1]).x2 = 320;
402 U4(rect[1]).y2 = 240;
403 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
404 * is ignored, the positive is still cleared afterwards
406 hr = IDirect3DDevice7_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
407 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
409 /* negative x, negative y */
410 U1(rect_negneg).x1 = 640;
411 U2(rect_negneg).y1 = 240;
412 U3(rect_negneg).x2 = 320;
413 U4(rect_negneg).y2 = 0;
414 hr = IDirect3DDevice7_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
415 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
417 color = getPixelColor(device, 160, 360); /* lower left quad */
418 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
419 color = getPixelColor(device, 160, 120); /* upper left quad */
420 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
421 color = getPixelColor(device, 480, 360); /* lower right quad */
422 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
423 color = getPixelColor(device, 480, 120); /* upper right quad */
424 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
439 static void fog_test(IDirect3DDevice7 *device)
443 float start = 0.0, end = 1.0;
446 /* Gets full z based fog with linear fog, no fog with specular color */
447 struct sVertex untransformed_1[] = {
448 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
449 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
450 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
451 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
453 /* Ok, I am too lazy to deal with transform matrices */
454 struct sVertex untransformed_2[] = {
455 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
456 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
457 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
458 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
460 /* Untransformed ones. Give them a different diffuse color to make the test look
461 * nicer. It also makes making sure that they are drawn correctly easier.
463 struct sVertexT transformed_1[] = {
464 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
465 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
466 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
467 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
469 struct sVertexT transformed_2[] = {
470 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
471 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
472 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
473 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
475 WORD Indices[] = {0, 1, 2, 2, 3, 0};
477 float ident_mat[16] =
479 1.0f, 0.0f, 0.0f, 0.0f,
480 0.0f, 1.0f, 0.0f, 0.0f,
481 0.0f, 0.0f, 1.0f, 0.0f,
482 0.0f, 0.0f, 0.0f, 1.0f
484 float world_mat1[16] =
486 1.0f, 0.0f, 0.0f, 0.0f,
487 0.0f, 1.0f, 0.0f, 0.0f,
488 0.0f, 0.0f, 1.0f, 0.0f,
489 0.0f, 0.0f, -0.5f, 1.0f
491 float world_mat2[16] =
493 1.0f, 0.0f, 0.0f, 0.0f,
494 0.0f, 1.0f, 0.0f, 0.0f,
495 0.0f, 0.0f, 1.0f, 0.0f,
496 0.0f, 0.0f, 1.0f, 1.0f
500 1.0f, 0.0f, 0.0f, 0.0f,
501 0.0f, 1.0f, 0.0f, 0.0f,
502 0.0f, 0.0f, 1.0f, 0.0f,
503 0.0f, 0.0f, -1.0f, 1.0f
506 struct sVertex far_quad1[] =
508 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
509 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
510 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
511 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
513 struct sVertex far_quad2[] =
515 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
516 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
517 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
518 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
521 memset(&caps, 0, sizeof(caps));
522 hr = IDirect3DDevice7_GetCaps(device, &caps);
523 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
524 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
525 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr);
527 /* Setup initial states: No lighting, fog on, fog color */
528 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
529 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
530 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE);
531 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
532 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */);
533 ok(hr == D3D_OK, "Setting fog color returned %08x\n", hr);
535 /* First test: Both table fog and vertex fog off */
536 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
537 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
538 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
539 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
541 /* Start = 0, end = 1. Should be default, but set them */
542 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start));
543 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
544 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end));
545 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
547 if(IDirect3DDevice7_BeginScene(device) == D3D_OK)
549 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
550 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
551 untransformed_1, 4, Indices, 6, 0);
552 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
554 /* That makes it use the Z value */
555 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
556 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
557 /* Untransformed, vertex fog != none (or table fog != none):
558 * Use the Z value as input into the equation
560 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
561 untransformed_2, 4, Indices, 6, 0);
562 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
564 /* transformed verts */
565 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
566 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
567 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
568 transformed_1, 4, Indices, 6, 0);
569 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
571 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
572 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
573 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
576 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
577 transformed_2, 4, Indices, 6, 0);
578 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
580 hr = IDirect3DDevice7_EndScene(device);
581 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
585 ok(FALSE, "BeginScene failed\n");
588 color = getPixelColor(device, 160, 360);
589 ok(color_match(color, 0x00FF0000, 1), "Untransformed vertex with no table or vertex fog has color %08x\n", color);
590 color = getPixelColor(device, 160, 120);
591 ok(color_match(color, 0x0000FF00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
592 color = getPixelColor(device, 480, 120);
593 ok(color_match(color, 0x00FFFF00, 1), "Transformed vertex with linear vertex fog has color %08x\n", color);
594 if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
596 color = getPixelColor(device, 480, 360);
597 ok(color_match(color, 0x0000FF00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
601 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
602 * The settings above result in no fogging with vertex fog
604 color = getPixelColor(device, 480, 120);
605 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
606 trace("Info: Table fog not supported by this device\n");
609 if (caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
611 /* A simple fog + non-identity world matrix test */
612 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat1);
613 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %#08x\n", hr);
615 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
616 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
617 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
618 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
620 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
621 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %#08x\n", hr);
623 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
625 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
626 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad1, 4, Indices, 6, 0);
627 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
629 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
630 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad2, 4, Indices, 6, 0);
631 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
633 hr = IDirect3DDevice7_EndScene(device);
634 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
638 ok(FALSE, "BeginScene failed\n");
641 color = getPixelColor(device, 160, 360);
642 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
643 color = getPixelColor(device, 160, 120);
644 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
646 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
647 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat2);
648 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
649 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)proj_mat);
650 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
652 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
653 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
655 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
657 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
658 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_1, 4, Indices, 6, 0);
659 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
661 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
662 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_2, 4, Indices, 6, 0);
663 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
665 hr = IDirect3DDevice7_EndScene(device);
666 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
670 ok(FALSE, "BeginScene failed\n");
673 color = getPixelColor(device, 160, 360);
674 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
675 color = getPixelColor(device, 160, 120);
676 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
678 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)ident_mat);
679 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
680 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)ident_mat);
681 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
685 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
688 /* Turn off the fog master switch to avoid confusing other tests */
689 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
690 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
693 static void blt_test(IDirect3DDevice7 *device)
695 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
699 memset(&ddsd, 0, sizeof(ddsd));
700 ddsd.dwSize = sizeof(ddsd);
701 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
702 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
705 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
706 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
707 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
709 /* Offscreen blits with the same source as destination */
712 RECT src_rect, dst_rect;
714 /* Blit the whole surface to itself */
715 hr = IDirectDrawSurface_Blt(offscreen, NULL, offscreen, NULL, 0, NULL);
716 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
718 /* Overlapped blit */
719 dst_rect.left = 0; dst_rect.right = 480;
720 dst_rect.top = 0; dst_rect.bottom = 480;
721 src_rect.left = 160; src_rect.right = 640;
722 src_rect.top = 0; src_rect.bottom = 480;
723 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
724 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
726 /* Overlapped blit, flip-y through source rectangle (not allowed) */
727 dst_rect.left = 0; dst_rect.right = 480;
728 dst_rect.top = 0; dst_rect.bottom = 480;
729 src_rect.left = 160; src_rect.right = 640;
730 src_rect.top = 480; src_rect.bottom = 0;
731 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
732 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface7_Blt returned %08x\n", hr);
734 /* Overlapped blit, with shrinking in x */
735 dst_rect.left = 0; dst_rect.right = 480;
736 dst_rect.top = 0; dst_rect.bottom = 480;
737 src_rect.left = 160; src_rect.right = 480;
738 src_rect.top = 0; src_rect.bottom = 480;
739 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
740 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
743 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
744 ok(hr == D3D_OK, "Unable to obtain a surface pointer to the backbuffer, hr = %08x\n", hr);
746 /* backbuffer ==> texture blits */
747 if(SUCCEEDED(hr) && offscreen)
749 RECT src_rect, dst_rect;
751 /* backbuffer ==> texture, src_rect=NULL, dst_rect=NULL, no scaling */
752 hr = IDirectDrawSurface_Blt(offscreen, NULL, backbuffer, NULL, 0, NULL);
753 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
755 /* backbuffer ==> texture, full surface blits, no scaling */
756 dst_rect.left = 0; dst_rect.right = 640;
757 dst_rect.top = 0; dst_rect.bottom = 480;
758 src_rect.left = 0; src_rect.right = 640;
759 src_rect.top = 0; src_rect.bottom = 480;
760 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
761 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
763 /* backbuffer ==> texture, flip in y-direction through source rectangle, no scaling (allowed) */
764 dst_rect.left = 0; dst_rect.right = 640;
765 dst_rect.top = 480; dst_rect.top = 0;
766 src_rect.left = 0; src_rect.right = 640;
767 src_rect.top = 0; src_rect.bottom = 480;
768 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
769 ok(hr == DD_OK, "backbuffer => texture flip-y src_rect failed with hr = %08x\n", hr);
771 /* backbuffer ==> texture, flip in x-direction through source rectangle, no scaling (not allowed) */
772 dst_rect.left = 640; dst_rect.right = 0;
773 dst_rect.top = 0; dst_rect.top = 480;
774 src_rect.left = 0; src_rect.right = 640;
775 src_rect.top = 0; src_rect.bottom = 480;
776 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
777 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x src_rect failed with hr = %08x\n", hr);
779 /* backbuffer ==> texture, flip in y-direction through destination rectangle (not allowed) */
780 dst_rect.left = 0; dst_rect.right = 640;
781 dst_rect.top = 0; dst_rect.top = 480;
782 src_rect.left = 0; src_rect.right = 640;
783 src_rect.top = 480; src_rect.bottom = 0;
784 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
785 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-y dst_rect failed with hr = %08x\n", hr);
787 /* backbuffer ==> texture, flip in x-direction through destination rectangle, no scaling (not allowed) */
788 dst_rect.left = 0; dst_rect.right = 640;
789 dst_rect.top = 0; dst_rect.top = 480;
790 src_rect.left = 640; src_rect.right = 0;
791 src_rect.top = 0; src_rect.bottom = 480;
792 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
793 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x dst_rect failed with hr = %08x\n", hr);
796 if(offscreen) IDirectDrawSurface7_Release(offscreen);
797 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
800 static void offscreen_test(IDirect3DDevice7 *device)
803 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
807 static float quad[][5] = {
808 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
809 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
810 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
811 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
814 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
815 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
817 memset(&ddsd, 0, sizeof(ddsd));
818 ddsd.dwSize = sizeof(ddsd);
819 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
820 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
823 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
824 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
825 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
830 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
831 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
836 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
837 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
838 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
839 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
840 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
841 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
842 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
843 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
844 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
845 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
848 win_skip("Tests would crash on W2K with a refdevice\n");
852 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
853 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
854 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
855 set_viewport_size(device);
856 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
857 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
859 /* Draw without textures - Should result in a white quad */
860 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
861 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
863 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
864 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
865 set_viewport_size(device);
867 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
868 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
870 /* This time with the texture */
871 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
872 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
874 IDirect3DDevice7_EndScene(device);
877 /* Center quad - should be white */
878 color = getPixelColor(device, 320, 240);
879 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
880 /* Some quad in the cleared part of the texture */
881 color = getPixelColor(device, 170, 240);
882 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
883 /* Part of the originally cleared back buffer */
884 color = getPixelColor(device, 10, 10);
885 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
887 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
888 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
889 * the offscreen rendering mode this test would succeed or fail
891 color = getPixelColor(device, 10, 470);
892 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
896 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
897 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetTexture returned %#x.\n", hr);
901 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
902 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetRenderTarget returned %#x.\n", hr);
903 IDirectDrawSurface7_Release(backbuffer);
906 IDirectDrawSurface7_Release(offscreen);
910 static void alpha_test(IDirect3DDevice7 *device)
913 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
914 DWORD color, red, green, blue;
917 struct vertex quad1[] =
919 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
920 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
921 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
922 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
924 struct vertex quad2[] =
926 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
927 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
928 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
929 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
931 static float composite_quad[][5] = {
932 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
933 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
934 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
935 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
938 /* Clear the render target with alpha = 0.5 */
939 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
940 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
942 memset(&ddsd, 0, sizeof(ddsd));
943 ddsd.dwSize = sizeof(ddsd);
944 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
947 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
948 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
949 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
950 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
951 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
952 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000ff;
953 U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
954 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
955 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
959 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
960 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
965 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
966 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
967 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
968 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
969 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
970 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
971 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
972 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
974 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
975 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
978 win_skip("Tests would crash on W2K with a refdevice\n");
982 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
984 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
985 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
988 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
989 * They give essentially ZERO and ONE blend factors
991 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
992 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
993 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
994 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
995 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
996 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
998 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
999 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1000 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1001 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1002 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1003 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1005 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
1006 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
1007 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
1008 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
1011 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
1012 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1013 set_viewport_size(device);
1014 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1015 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1017 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1018 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1019 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1020 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1021 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
1022 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1024 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
1025 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1026 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1027 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1028 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1029 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1031 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
1032 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1033 set_viewport_size(device);
1035 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1036 * Disable alpha blending for the final composition
1038 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
1039 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1041 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
1042 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1043 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
1044 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1045 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
1046 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1048 hr = IDirect3DDevice7_EndScene(device);
1049 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1052 color = getPixelColor(device, 160, 360);
1053 red = (color & 0x00ff0000) >> 16;
1054 green = (color & 0x0000ff00) >> 8;
1055 blue = (color & 0x000000ff);
1056 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1057 "SRCALPHA on frame buffer returned color 0x%08x, expected 0x00bf4000\n", color);
1059 color = getPixelColor(device, 160, 120);
1060 red = (color & 0x00ff0000) >> 16;
1061 green = (color & 0x0000ff00) >> 8;
1062 blue = (color & 0x000000ff);
1063 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
1064 "DSTALPHA on frame buffer returned color 0x%08x, expected 0x000000ff\n", color);
1066 color = getPixelColor(device, 480, 360);
1067 red = (color & 0x00ff0000) >> 16;
1068 green = (color & 0x0000ff00) >> 8;
1069 blue = (color & 0x000000ff);
1070 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1071 "SRCALPHA on texture returned color 0x%08x, expected 0x00bf4000\n", color);
1073 color = getPixelColor(device, 480, 120);
1074 red = (color & 0x00ff0000) >> 16;
1075 green = (color & 0x0000ff00) >> 8;
1076 blue = (color & 0x000000ff);
1077 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
1078 "DSTALPHA on texture returned color 0x%08x, expected 0x00800080\n", color);
1081 if(offscreen) IDirectDrawSurface7_Release(offscreen);
1082 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
1085 static void rhw_zero_test(IDirect3DDevice7 *device)
1087 /* Test if it will render a quad correctly when vertex rhw = 0 */
1097 {0, 100, 0, 0, 0xffffffff},
1098 {0, 0, 0, 0, 0xffffffff},
1099 {100, 100, 0, 0, 0xffffffff},
1100 {100, 0, 0, 0, 0xffffffff},
1103 /* Clear to black */
1104 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
1105 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1107 hr = IDirect3DDevice7_BeginScene(device);
1108 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
1110 if (SUCCEEDED(hr)) {
1111 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
1112 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1114 hr = IDirect3DDevice7_EndScene(device);
1115 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1118 color = getPixelColor(device, 5, 5);
1119 ok(color == 0xffffff ||
1120 broken(color == 0), /* VMware */
1121 "Got color %08x, expected 00ffffff\n", color);
1123 color = getPixelColor(device, 105, 105);
1124 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1127 static BOOL D3D1_createObjects(void)
1132 D3DEXECUTEBUFFERDESC exdesc;
1133 D3DVIEWPORT vp_data;
1135 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1136 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1138 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1143 wc.lpfnWndProc = DefWindowProc;
1144 wc.lpszClassName = "texturemapblend_test_wc";
1146 window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1148 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1149 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1154 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
1156 /* 24 bit is fine too */
1157 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
1159 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1164 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1165 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1170 memset(&ddsd, 0, sizeof(ddsd));
1171 ddsd.dwSize = sizeof(ddsd);
1172 ddsd.dwFlags = DDSD_CAPS;
1173 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
1174 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1175 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1180 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
1182 trace("Creating a HAL device failed, trying Ref\n");
1183 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
1185 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
1190 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1191 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1196 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1197 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1198 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1199 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1200 vp_data.dwSize = sizeof(vp_data);
1203 vp_data.dwWidth = 640;
1204 vp_data.dwHeight = 480;
1205 vp_data.dvScaleX = 1;
1206 vp_data.dvScaleY = 1;
1207 vp_data.dvMaxX = 640;
1208 vp_data.dvMaxY = 480;
1211 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1212 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1214 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1215 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1216 exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1217 exdesc.dwBufferSize = 512;
1218 exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
1219 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
1220 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
1228 static void D3D1_releaseObjects(void)
1230 if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1231 if(Surface1) IDirectDrawSurface_Release(Surface1);
1232 if(Viewport) IDirect3DViewport_Release(Viewport);
1233 if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1234 if(Direct3D1) IDirect3D_Release(Direct3D1);
1235 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1236 if(window) DestroyWindow(window);
1239 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
1244 RECT rectToLock = {x, y, x+1, y+1};
1245 IDirectDrawSurface *surf = NULL;
1247 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
1248 * to an offscreen surface and lock it instead of the front buffer
1250 memset(&ddsd, 0, sizeof(ddsd));
1251 ddsd.dwSize = sizeof(ddsd);
1252 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1253 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
1255 ddsd.dwHeight = 480;
1256 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
1257 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
1258 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
1261 trace("cannot create helper surface\n");
1265 memset(&ddsd, 0, sizeof(ddsd));
1266 ddsd.dwSize = sizeof(ddsd);
1267 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1269 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
1270 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
1273 trace("Cannot blit\n");
1278 hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
1281 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
1286 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
1287 * really important for these tests
1289 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
1290 hr = IDirectDrawSurface_Unlock(surf, NULL);
1293 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
1297 IDirectDrawSurface_Release(surf);
1301 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
1302 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
1303 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
1304 ((D3DINSTRUCTION*)(ptr))->wCount = count;\
1305 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1307 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
1308 U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
1309 U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
1310 ptr = ((D3DSTATE*)(ptr))+1; } while (0)
1312 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
1313 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
1314 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
1315 ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1316 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1317 ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1318 ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1319 ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1320 ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1321 ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1322 ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1324 #define EXEBUF_END(ptr) do {\
1325 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1326 ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1327 ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1328 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1330 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1331 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1332 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1333 ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1334 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1335 U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1336 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1337 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1338 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1339 ptr = ((D3DTRIANGLE*)ptr)+1;\
1340 U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1341 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1342 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1343 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1344 ptr = ((D3DTRIANGLE*)(ptr))+1;\
1347 static HRESULT CALLBACK TextureFormatEnumCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext)
1349 if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1350 *(BOOL*)lpContext = TRUE;
1353 return DDENUMRET_OK;
1356 static void D3D1_TextureMapBlendTest(void)
1360 D3DEXECUTEBUFFERDESC exdesc;
1361 D3DEXECUTEDATA exdata;
1363 RECT rect = { 0, 0, 64, 128 };
1364 DWORD color, red, blue, green;
1365 void *exe_buffer_ptr;
1367 D3DTEXTUREHANDLE htex;
1369 IDirectDrawSurface *TexSurface = NULL;
1370 IDirect3DTexture *Texture = NULL;
1371 IDirectDrawPalette *Palette = NULL;
1372 PALETTEENTRY table1[256];
1373 BOOL p8_textures_supported = FALSE;
1383 {0.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1384 {640.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1385 {640.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1386 {0.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1387 {0.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1388 {640.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1389 {640.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1390 {0.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1393 {0.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1394 {640.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1395 {640.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1396 {0.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1397 {0.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1398 {640.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1399 {640.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1400 {0.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1403 /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1404 memset (&ddsd, 0, sizeof (ddsd));
1405 ddsd.dwSize = sizeof (ddsd);
1406 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1407 ddsd.dwHeight = 128;
1409 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1410 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1411 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1412 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1413 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1414 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1415 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1416 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1417 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1418 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1420 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1424 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1426 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1428 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1432 memset(&ddbltfx, 0, sizeof(ddbltfx));
1433 ddbltfx.dwSize = sizeof(ddbltfx);
1434 U5(ddbltfx).dwFillColor = 0;
1435 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1436 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1438 U5(ddbltfx).dwFillColor = 0xff0000ff;
1439 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1440 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1441 U5(ddbltfx).dwFillColor = 0x800000ff;
1442 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1443 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1445 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1446 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1447 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1448 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1450 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1454 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1456 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1458 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1460 EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1461 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, exe_buffer_ptr);
1462 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE, FALSE, exe_buffer_ptr);
1463 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE, FALSE, exe_buffer_ptr);
1464 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE, FALSE, exe_buffer_ptr);
1465 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_NEAREST, exe_buffer_ptr);
1466 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_NEAREST, exe_buffer_ptr);
1467 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE , D3DFILL_SOLID, exe_buffer_ptr);
1468 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA, exe_buffer_ptr);
1469 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA, exe_buffer_ptr);
1470 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1471 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, exe_buffer_ptr);
1472 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1473 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1474 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1476 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1477 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1479 EXEBUF_END(exe_buffer_ptr);
1481 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1483 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1485 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1488 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1489 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1490 exdata.dwVertexCount = 8;
1491 exdata.dwInstructionOffset = 256;
1492 exdata.dwInstructionLength = exe_length;
1493 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1494 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1496 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1497 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1499 if (SUCCEEDED(hr)) {
1500 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1501 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1502 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1503 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1506 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1507 red = (color & 0x00ff0000) >> 16;
1508 green = (color & 0x0000ff00) >> 8;
1509 blue = (color & 0x000000ff);
1510 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1512 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1513 red = (color & 0x00ff0000) >> 16;
1514 green = (color & 0x0000ff00) >> 8;
1515 blue = (color & 0x000000ff);
1516 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1518 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1519 red = (color & 0x00ff0000) >> 16;
1520 green = (color & 0x0000ff00) >> 8;
1521 blue = (color & 0x000000ff);
1522 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1524 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1525 red = (color & 0x00ff0000) >> 16;
1526 green = (color & 0x0000ff00) >> 8;
1527 blue = (color & 0x000000ff);
1528 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1530 /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1531 if(Texture) IDirect3DTexture_Release(Texture);
1533 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1536 memset (&ddsd, 0, sizeof (ddsd));
1537 ddsd.dwSize = sizeof (ddsd);
1538 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1539 ddsd.dwHeight = 128;
1541 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1542 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1543 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1544 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1545 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1546 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1547 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1549 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1550 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1552 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1556 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1558 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1560 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1564 memset(&ddbltfx, 0, sizeof(ddbltfx));
1565 ddbltfx.dwSize = sizeof(ddbltfx);
1566 U5(ddbltfx).dwFillColor = 0;
1567 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1568 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1570 U5(ddbltfx).dwFillColor = 0xff0000ff;
1571 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1572 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1573 U5(ddbltfx).dwFillColor = 0x800000ff;
1574 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1575 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1577 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1578 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1579 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1580 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1582 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1586 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1588 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1590 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1592 EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1593 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1594 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1595 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1597 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1598 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1600 EXEBUF_END(exe_buffer_ptr);
1602 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1604 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1606 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1609 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1610 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1611 exdata.dwVertexCount = 8;
1612 exdata.dwInstructionOffset = 256;
1613 exdata.dwInstructionLength = exe_length;
1614 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1615 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1617 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1618 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1620 if (SUCCEEDED(hr)) {
1621 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1622 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1623 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1624 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1627 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1628 red = (color & 0x00ff0000) >> 16;
1629 green = (color & 0x0000ff00) >> 8;
1630 blue = (color & 0x000000ff);
1631 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1633 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1634 red = (color & 0x00ff0000) >> 16;
1635 green = (color & 0x0000ff00) >> 8;
1636 blue = (color & 0x000000ff);
1637 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1639 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1640 red = (color & 0x00ff0000) >> 16;
1641 green = (color & 0x0000ff00) >> 8;
1642 blue = (color & 0x000000ff);
1643 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1645 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1646 red = (color & 0x00ff0000) >> 16;
1647 green = (color & 0x0000ff00) >> 8;
1648 blue = (color & 0x000000ff);
1649 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1651 /* 3) Test RGB - should multiply color components from diffuse color and texture */
1652 if(Texture) IDirect3DTexture_Release(Texture);
1654 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1657 memset (&ddsd, 0, sizeof (ddsd));
1658 ddsd.dwSize = sizeof (ddsd);
1659 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1660 ddsd.dwHeight = 128;
1662 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1663 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1664 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1665 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1666 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1667 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1668 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1669 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1670 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1671 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1673 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1677 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1679 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1681 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1685 memset(&ddbltfx, 0, sizeof(ddbltfx));
1686 ddbltfx.dwSize = sizeof(ddbltfx);
1687 U5(ddbltfx).dwFillColor = 0;
1688 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1689 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1691 U5(ddbltfx).dwFillColor = 0x00ffffff;
1692 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1693 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1694 U5(ddbltfx).dwFillColor = 0x00ffff80;
1695 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1696 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1698 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1699 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1700 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1701 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1703 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1707 memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1709 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1711 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1713 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1714 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1715 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1716 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1717 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1719 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1720 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1722 EXEBUF_END(exe_buffer_ptr);
1724 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1726 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1728 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1731 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1732 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1733 exdata.dwVertexCount = 8;
1734 exdata.dwInstructionOffset = 256;
1735 exdata.dwInstructionLength = exe_length;
1736 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1737 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1739 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1740 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1742 if (SUCCEEDED(hr)) {
1743 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1744 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1745 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1746 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1749 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1750 red = (color & 0x00ff0000) >> 16;
1751 green = (color & 0x0000ff00) >> 8;
1752 blue = (color & 0x000000ff);
1753 ok(red == 0xff && green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1755 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1756 red = (color & 0x00ff0000) >> 16;
1757 green = (color & 0x0000ff00) >> 8;
1758 blue = (color & 0x000000ff);
1759 ok(red == 0xff && green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1761 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1762 red = (color & 0x00ff0000) >> 16;
1763 green = (color & 0x0000ff00) >> 8;
1764 blue = (color & 0x000000ff);
1765 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1767 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1768 red = (color & 0x00ff0000) >> 16;
1769 green = (color & 0x0000ff00) >> 8;
1770 blue = (color & 0x000000ff);
1771 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1773 /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1774 if(Texture) IDirect3DTexture_Release(Texture);
1776 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1779 memset (&ddsd, 0, sizeof (ddsd));
1780 ddsd.dwSize = sizeof (ddsd);
1781 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1782 ddsd.dwHeight = 128;
1784 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1785 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1786 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1787 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
1788 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xf800;
1789 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07e0;
1790 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001f;
1792 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1793 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1795 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1799 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1801 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1803 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1807 memset(&ddbltfx, 0, sizeof(ddbltfx));
1808 ddbltfx.dwSize = sizeof(ddbltfx);
1809 U5(ddbltfx).dwFillColor = 0;
1810 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1811 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1812 U5(ddbltfx).dwFillColor = 0xf800;
1813 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1814 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1815 U5(ddbltfx).dwFillColor = 0x001f;
1816 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1817 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1819 clrKey.dwColorSpaceLowValue = 0x001f;
1820 clrKey.dwColorSpaceHighValue = 0x001f;
1821 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1822 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1824 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1825 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1826 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1827 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1829 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1833 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1835 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1837 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1839 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1840 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1841 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1842 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1843 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1845 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1846 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1848 EXEBUF_END(exe_buffer_ptr);
1850 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1852 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1854 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1857 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1858 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1859 exdata.dwVertexCount = 8;
1860 exdata.dwInstructionOffset = 256;
1861 exdata.dwInstructionLength = exe_length;
1862 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1863 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1865 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1866 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1868 if (SUCCEEDED(hr)) {
1869 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1870 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1871 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1872 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1875 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1876 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1878 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1879 red = (color & 0x00ff0000) >> 16;
1880 green = (color & 0x0000ff00) >> 8;
1881 blue = (color & 0x000000ff);
1882 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1884 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1885 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1887 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1888 red = (color & 0x00ff0000) >> 16;
1889 green = (color & 0x0000ff00) >> 8;
1890 blue = (color & 0x000000ff);
1891 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1893 /* 5) Test alpha again, now with color keyed P8 texture */
1894 if(Texture) IDirect3DTexture_Release(Texture);
1896 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1899 hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1900 &p8_textures_supported);
1901 ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1903 if (!p8_textures_supported) {
1904 skip("device has no P8 texture support, skipping test\n");
1906 memset (&ddsd, 0, sizeof (ddsd));
1907 ddsd.dwSize = sizeof (ddsd);
1908 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1909 ddsd.dwHeight = 128;
1911 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1912 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1913 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1914 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1916 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1917 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1919 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1923 memset(table1, 0, sizeof(table1));
1924 table1[0].peBlue = 0xff;
1925 table1[1].peRed = 0xff;
1927 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1928 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1930 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1934 hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1935 ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1937 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1939 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1941 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1945 memset(&ddbltfx, 0, sizeof(ddbltfx));
1946 ddbltfx.dwSize = sizeof(ddbltfx);
1947 U5(ddbltfx).dwFillColor = 0;
1948 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1949 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1950 U5(ddbltfx).dwFillColor = 0;
1951 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1952 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1953 U5(ddbltfx).dwFillColor = 1;
1954 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1955 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1957 clrKey.dwColorSpaceLowValue = 1;
1958 clrKey.dwColorSpaceHighValue = 1;
1959 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1960 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1962 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1963 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1964 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1965 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1967 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1971 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1973 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1975 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1977 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1978 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1979 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1980 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1981 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1983 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1984 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1986 EXEBUF_END(exe_buffer_ptr);
1988 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1990 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1992 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1995 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1996 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1997 exdata.dwVertexCount = 8;
1998 exdata.dwInstructionOffset = 256;
1999 exdata.dwInstructionLength = exe_length;
2000 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
2001 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
2003 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2004 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2006 if (SUCCEEDED(hr)) {
2007 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
2008 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
2009 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2010 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2013 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2014 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2016 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
2017 red = (color & 0x00ff0000) >> 16;
2018 green = (color & 0x0000ff00) >> 8;
2019 blue = (color & 0x000000ff);
2020 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
2022 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
2023 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2025 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
2026 red = (color & 0x00ff0000) >> 16;
2027 green = (color & 0x0000ff00) >> 8;
2028 blue = (color & 0x000000ff);
2029 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
2034 if (Palette) IDirectDrawPalette_Release(Palette);
2035 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
2036 if (Texture) IDirect3DTexture_Release(Texture);
2039 static void D3D1_ViewportClearTest(void)
2042 IDirect3DMaterial *bgMaterial = NULL;
2044 D3DMATERIALHANDLE hMat;
2045 D3DVIEWPORT vp_data;
2046 IDirect3DViewport *Viewport2 = NULL;
2047 DWORD color, red, green, blue;
2049 hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
2050 ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
2055 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
2056 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
2061 hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
2062 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
2063 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
2064 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
2065 vp_data.dwSize = sizeof(vp_data);
2068 vp_data.dwWidth = 100;
2069 vp_data.dwHeight = 100;
2070 vp_data.dvScaleX = 1;
2071 vp_data.dvScaleY = 1;
2072 vp_data.dvMaxX = 100;
2073 vp_data.dvMaxY = 100;
2076 hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
2077 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
2079 memset(&mat, 0, sizeof(mat));
2080 mat.dwSize = sizeof(mat);
2081 U1(U(mat).diffuse).r = 1.0f;
2082 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2083 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2085 hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
2086 ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
2088 hr = IDirect3DViewport_SetBackground(Viewport, hMat);
2089 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2090 hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
2091 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2093 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2094 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2096 if (SUCCEEDED(hr)) {
2099 U1(rect).x1 = U2(rect).y1 = 0;
2103 hr = IDirect3DViewport_Clear(Viewport, 1, &rect, D3DCLEAR_TARGET);
2104 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2106 memset(&mat, 0, sizeof(mat));
2107 mat.dwSize = sizeof(mat);
2108 U3(U(mat).diffuse).b = 1.0f;
2109 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2110 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2112 hr = IDirect3DViewport_Clear(Viewport2, 1, &rect, D3DCLEAR_TARGET);
2113 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2115 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2116 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2119 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2120 red = (color & 0x00ff0000) >> 16;
2121 green = (color & 0x0000ff00) >> 8;
2122 blue = (color & 0x000000ff);
2123 ok((red == 0xff && green == 0 && blue == 0) ||
2124 broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
2125 "Got color %08x, expected 00ff0000\n", color);
2127 color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
2128 red = (color & 0x00ff0000) >> 16;
2129 green = (color & 0x0000ff00) >> 8;
2130 blue = (color & 0x000000ff);
2131 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
2135 if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
2136 if (Viewport2) IDirect3DViewport_Release(Viewport2);
2139 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
2143 DDSURFACEDESC2 ddsd;
2144 RECT rectToLock = {x, y, x+1, y+1};
2145 IDirectDrawSurface4 *surf = NULL;
2147 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
2148 * to an offscreen surface and lock it instead of the front buffer
2150 memset(&ddsd, 0, sizeof(ddsd));
2151 ddsd.dwSize = sizeof(ddsd);
2152 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2153 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
2155 ddsd.dwHeight = 480;
2156 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
2157 hr = IDirectDraw4_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
2158 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2161 trace("cannot create helper surface\n");
2165 memset(&ddsd, 0, sizeof(ddsd));
2166 ddsd.dwSize = sizeof(ddsd);
2167 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2169 hr = IDirectDrawSurface4_BltFast(surf, 0, 0, Surface, NULL, 0);
2170 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
2173 trace("Cannot blit\n");
2178 hr = IDirectDrawSurface4_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
2181 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
2186 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
2187 * really important for these tests
2189 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
2190 hr = IDirectDrawSurface4_Unlock(surf, NULL);
2193 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
2197 IDirectDrawSurface4_Release(surf);
2201 static void D3D3_ViewportClearTest(void)
2204 IDirectDraw *DirectDraw1 = NULL;
2205 IDirectDraw4 *DirectDraw4 = NULL;
2206 IDirectDrawSurface4 *Primary = NULL;
2207 IDirect3D3 *Direct3D3 = NULL;
2208 IDirect3DViewport3 *Viewport3 = NULL;
2209 IDirect3DViewport3 *SmallViewport3 = NULL;
2210 IDirect3DDevice3 *Direct3DDevice3 = NULL;
2212 DDSURFACEDESC2 ddsd;
2213 D3DVIEWPORT2 vp_data;
2214 DWORD color, red, green, blue;
2216 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
2217 0.0f, 1.0f, 0.0f, 0.0f,
2218 0.0f, 0.0f, 1.0f, 0.0f,
2219 0.0f, 0.0f, 0.0f, 1.0f };
2220 struct vertex quad[] =
2222 {-1.0f, -1.0f, 0.1f, 0xffffffff},
2223 {-1.0f, 1.0f, 0.1f, 0xffffffff},
2224 { 1.0f, 1.0f, 0.1f, 0xffffffff},
2225 { 1.0f, -1.0f, 0.1f, 0xffffffff},
2228 WORD Indices[] = {0, 1, 2, 2, 3, 0};
2229 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
2231 wc.lpfnWndProc = DefWindowProc;
2232 wc.lpszClassName = "D3D3_ViewportClearTest_wc";
2234 window = CreateWindow("D3D3_ViewportClearTest_wc", "D3D3_ViewportClearTest",
2235 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2237 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2238 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2239 if(FAILED(hr)) goto out;
2241 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2242 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2243 if(FAILED(hr)) goto out;
2245 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2247 /* 24 bit is fine too */
2248 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2250 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2251 if (FAILED(hr)) goto out;
2253 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void**)&DirectDraw4);
2254 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
2255 if(FAILED(hr)) goto out;
2257 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2258 ddsd.dwSize = sizeof(DDSURFACEDESC2);
2259 ddsd.dwFlags = DDSD_CAPS;
2260 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
2262 hr = IDirectDraw_CreateSurface(DirectDraw4, &ddsd, &Primary, NULL);
2263 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2264 if(FAILED(hr)) goto out;
2266 hr = IDirectDraw4_QueryInterface(DirectDraw4, &IID_IDirect3D3, (void**)&Direct3D3);
2267 ok(hr==DD_OK, "IDirectDraw4_QueryInterface returned: %08x\n", hr);
2268 if(FAILED(hr)) goto out;
2270 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DHALDevice, Primary, &Direct3DDevice3, NULL);
2272 trace("Creating a HAL device failed, trying Ref\n");
2273 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DRefDevice, Primary, &Direct3DDevice3, NULL);
2275 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
2276 if(FAILED(hr)) goto out;
2278 hr = IDirect3D3_CreateViewport(Direct3D3, &Viewport3, NULL);
2279 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2280 if(FAILED(hr)) goto out;
2282 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, Viewport3);
2283 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2285 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2286 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2287 vp_data.dwWidth = 640;
2288 vp_data.dwHeight = 480;
2289 vp_data.dvClipX = -1.0f;
2290 vp_data.dvClipWidth = 2.0f;
2291 vp_data.dvClipY = 1.0f;
2292 vp_data.dvClipHeight = 2.0f;
2293 vp_data.dvMaxZ = 1.0f;
2294 hr = IDirect3DViewport3_SetViewport2(Viewport3, &vp_data);
2295 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2297 hr = IDirect3D3_CreateViewport(Direct3D3, &SmallViewport3, NULL);
2298 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2299 if(FAILED(hr)) goto out;
2301 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, SmallViewport3);
2302 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2304 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2305 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2308 vp_data.dwWidth = 100;
2309 vp_data.dwHeight = 100;
2310 vp_data.dvClipX = -1.0f;
2311 vp_data.dvClipWidth = 2.0f;
2312 vp_data.dvClipY = 1.0f;
2313 vp_data.dvClipHeight = 2.0f;
2314 vp_data.dvMaxZ = 1.0f;
2315 hr = IDirect3DViewport3_SetViewport2(SmallViewport3, &vp_data);
2316 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2318 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2319 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2321 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
2322 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2323 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
2324 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2325 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
2326 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2327 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CLIPPING, FALSE);
2328 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2329 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ZENABLE, FALSE);
2330 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2331 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_FOGENABLE, FALSE);
2332 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2333 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_STENCILENABLE, FALSE);
2334 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2335 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
2336 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2337 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
2338 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2339 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
2340 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState failed with %08x\n", hr);
2341 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
2342 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2344 if (SUCCEEDED(hr)) {
2345 U1(rect).x1 = U2(rect).y1 = 0;
2349 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x00ff00, 0.0f, 0);
2350 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2352 hr = IDirect3DViewport3_Clear2(SmallViewport3, 1, &rect, D3DCLEAR_TARGET, 0xff0000, 0.0f, 0);
2353 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2355 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2356 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2359 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2360 red = (color & 0x00ff0000) >> 16;
2361 green = (color & 0x0000ff00) >> 8;
2362 blue = (color & 0x000000ff);
2363 ok(red == 0 && green == 0xff && blue == 0, "Got color %08x, expected 0000ff00\n", color);
2365 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2366 red = (color & 0x00ff0000) >> 16;
2367 green = (color & 0x0000ff00) >> 8;
2368 blue = (color & 0x000000ff);
2369 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000\n", color);
2371 /* Test that clearing viewport doesn't interfere with rendering to previously active viewport. */
2372 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2373 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2375 if (SUCCEEDED(hr)) {
2376 hr = IDirect3DDevice3_SetCurrentViewport(Direct3DDevice3, SmallViewport3);
2377 ok(hr == D3D_OK, "IDirect3DDevice3_SetCurrentViewport failed with %08x\n", hr);
2379 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x000000, 0.0f, 0);
2380 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2382 hr = IDirect3DDevice3_DrawIndexedPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf, quad, 4 /* NumVerts */,
2383 Indices, 6 /* Indexcount */, 0 /* flags */);
2384 ok(hr == D3D_OK, "IDirect3DDevice3_DrawIndexedPrimitive failed with %08x\n", hr);
2386 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2387 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2390 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2391 red = (color & 0x00ff0000) >> 16;
2392 green = (color & 0x0000ff00) >> 8;
2393 blue = (color & 0x000000ff);
2394 ok(red == 0 && green == 0 && blue == 0, "Got color %08x, expected 00000000\n", color);
2396 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2397 red = (color & 0x00ff0000) >> 16;
2398 green = (color & 0x0000ff00) >> 8;
2399 blue = (color & 0x000000ff);
2400 ok(red == 0xff && green == 0xff && blue == 0xff, "Got color %08x, expected 00ffffff\n", color);
2404 if (SmallViewport3) IDirect3DViewport3_Release(SmallViewport3);
2405 if (Viewport3) IDirect3DViewport3_Release(Viewport3);
2406 if (Direct3DDevice3) IDirect3DDevice3_Release(Direct3DDevice3);
2407 if (Direct3D3) IDirect3D3_Release(Direct3D3);
2408 if (Primary) IDirectDrawSurface4_Release(Primary);
2409 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
2410 if (DirectDraw4) IDirectDraw4_Release(DirectDraw4);
2411 if(window) DestroyWindow(window);
2414 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
2421 memset(&ddsd, 0, sizeof(ddsd));
2422 ddsd.dwSize = sizeof(ddsd);
2424 hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
2425 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2427 p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2429 for (i = 0; i < h; i++) {
2430 for (i1 = 0; i1 < w; i1++) {
2433 p += U1(ddsd).lPitch;
2436 hr = IDirectDrawSurface_Unlock(dest, NULL);
2437 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2440 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
2442 COLORREF clr = CLR_INVALID;
2446 hr = IDirectDrawSurface_GetDC(Surface, &hdc);
2447 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2449 if (SUCCEEDED(hr)) {
2450 clr = GetPixel(hdc, x, y);
2452 hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
2453 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2459 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
2463 for (i = 0; i < 256; i++) {
2464 if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
2465 table1[i].peBlue != table2[i].rgbBlue) return FALSE;
2471 static void p8_primary_test(void)
2473 /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
2477 PALETTEENTRY entries[256];
2478 RGBQUAD coltable[256];
2480 IDirectDrawPalette *ddprimpal = NULL;
2481 IDirectDrawSurface *offscreen = NULL;
2487 unsigned differences;
2489 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
2490 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
2492 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2497 wc.lpfnWndProc = DefWindowProc;
2498 wc.lpszClassName = "p8_primary_test_wc";
2500 window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2502 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2503 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2508 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
2509 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2514 memset(&ddsd, 0, sizeof(ddsd));
2515 ddsd.dwSize = sizeof(ddsd);
2516 ddsd.dwFlags = DDSD_CAPS;
2517 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2518 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
2519 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
2524 memset(entries, 0, sizeof(entries));
2525 entries[0].peRed = 0xff;
2526 entries[1].peGreen = 0xff;
2527 entries[2].peBlue = 0xff;
2529 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
2530 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2532 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
2536 hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
2537 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2539 p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
2541 color = getPixelColor_GDI(Surface1, 10, 10);
2542 ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
2543 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2544 GetRValue(color), GetGValue(color), GetBValue(color));
2546 memset(&ddbltfx, 0, sizeof(ddbltfx));
2547 ddbltfx.dwSize = sizeof(ddbltfx);
2548 U5(ddbltfx).dwFillColor = 0;
2549 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2550 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2552 color = getPixelColor_GDI(Surface1, 10, 10);
2553 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
2554 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
2555 GetRValue(color), GetGValue(color), GetBValue(color));
2557 memset(&ddbltfx, 0, sizeof(ddbltfx));
2558 ddbltfx.dwSize = sizeof(ddbltfx);
2559 U5(ddbltfx).dwFillColor = 1;
2560 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2561 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2563 color = getPixelColor_GDI(Surface1, 10, 10);
2564 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2565 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2566 GetRValue(color), GetGValue(color), GetBValue(color));
2568 memset (&ddsd, 0, sizeof (ddsd));
2569 ddsd.dwSize = sizeof (ddsd);
2570 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2573 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
2574 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2575 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2576 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2577 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2579 broken(hr == DDERR_INVALIDPIXELFORMAT) || /* VMware */
2580 broken(hr == DDERR_NODIRECTDRAWHW), /* VMware */
2581 "IDirectDraw_CreateSurface returned %08x\n", hr);
2582 if (FAILED(hr)) goto out;
2584 memset(entries, 0, sizeof(entries));
2585 for (i = 0; i < 256; i++) {
2586 entries[i].peBlue = i;
2588 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2589 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2591 hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
2592 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2593 i = GetDIBColorTable(hdc, 0, 256, coltable);
2594 ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
2595 hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
2596 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2598 ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
2600 p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 2);
2602 memset(entries, 0, sizeof(entries));
2603 entries[0].peRed = 0xff;
2604 entries[1].peGreen = 0xff;
2605 entries[2].peBlue = 0xff;
2606 entries[3].peRed = 0x80;
2607 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2608 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2610 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2611 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2613 color = getPixelColor_GDI(Surface1, 1, 1);
2614 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2615 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2616 GetRValue(color), GetGValue(color), GetBValue(color));
2618 /* Color keyed blit. */
2619 p8_surface_fill_rect(offscreen, 0, 0, 8, 8, 3);
2620 clrKey.dwColorSpaceLowValue = 3;
2621 clrKey.dwColorSpaceHighValue = 3;
2622 hr = IDirectDrawSurface_SetColorKey(offscreen, DDCKEY_SRCBLT, &clrKey);
2623 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
2625 hr = IDirectDrawSurface_BltFast(Surface1, 100, 100, offscreen, NULL, DDBLTFAST_SRCCOLORKEY);
2626 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2628 color = getPixelColor_GDI(Surface1, 105, 105);
2629 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2630 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2631 GetRValue(color), GetGValue(color), GetBValue(color));
2633 color = getPixelColor_GDI(Surface1, 112, 112);
2634 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2635 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2636 GetRValue(color), GetGValue(color), GetBValue(color));
2643 memset(&ddbltfx, 0, sizeof(ddbltfx));
2644 ddbltfx.dwSize = sizeof(ddbltfx);
2645 ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 2;
2646 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2647 DDBLT_WAIT | DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2648 ok(hr==DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned: %x\n", hr);
2649 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2650 DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2651 ok(hr==DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2653 color = getPixelColor_GDI(Surface1, 105, 205);
2654 ok(GetRValue(color) == 0x80 && GetGValue(color) == 0 && GetBValue(color) == 0,
2655 "got R %02X G %02X B %02X, expected R 80 G 00 B 00\n",
2656 GetRValue(color), GetGValue(color), GetBValue(color));
2658 color = getPixelColor_GDI(Surface1, 112, 212);
2659 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2660 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2661 GetRValue(color), GetGValue(color), GetBValue(color));
2663 /* Test blitting and locking patterns that are likely to trigger bugs in opengl renderer (p8
2664 surface conversion and uploading/downloading to/from opengl texture). Similar patterns (
2665 blitting front buffer areas to/from an offscreen surface mixed with locking) are used by C&C
2667 IDirectDrawSurface_Release(offscreen);
2669 memset (&ddsd, 0, sizeof (ddsd));
2670 ddsd.dwSize = sizeof (ddsd);
2671 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2673 ddsd.dwHeight = 480;
2674 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2675 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2676 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2677 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2678 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2679 ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
2681 if (FAILED(hr)) goto out;
2683 /* Test two times, first time front buffer has a palette and second time front buffer
2684 has no palette; the latter is somewhat contrived example, but an app could set
2685 front buffer palette later. */
2686 for (i2 = 0; i2 < 2; i2++) {
2688 hr = IDirectDrawSurface_SetPalette(Surface1, NULL);
2689 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2692 memset(&ddsd, 0, sizeof(ddsd));
2693 ddsd.dwSize = sizeof(ddsd);
2694 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2695 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2697 for (i = 0; i < 256; i++) {
2698 unsigned x = (i % 128) * 4;
2699 unsigned y = (i / 128) * 4;
2700 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2702 for (i1 = 0; i1 < 4; i1++) {
2703 p[0] = p[1] = p[2] = p[3] = i;
2704 p += U1(ddsd).lPitch;
2708 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2709 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2711 hr = IDirectDrawSurface_BltFast(offscreen, 0, 0, Surface1, NULL, 0);
2712 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2714 /* This ensures offscreen surface contents will be downloaded to system memory. */
2715 memset(&ddsd, 0, sizeof(ddsd));
2716 ddsd.dwSize = sizeof(ddsd);
2717 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2718 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2719 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2720 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2722 /* Offscreen surface data will have to be converted and uploaded to texture. */
2727 hr = IDirectDrawSurface_BltFast(offscreen, 600, 400, Surface1, &rect, 0);
2728 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2730 /* This ensures offscreen surface contents will be downloaded to system memory. */
2731 memset(&ddsd, 0, sizeof(ddsd));
2732 ddsd.dwSize = sizeof(ddsd);
2733 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2734 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2735 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2736 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2738 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2739 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2741 memset(&ddsd, 0, sizeof(ddsd));
2742 ddsd.dwSize = sizeof(ddsd);
2743 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2744 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2748 for (i = 0; i < 256; i++) {
2749 unsigned x = (i % 128) * 4 + 1;
2750 unsigned y = (i / 128) * 4 + 1;
2751 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2753 if (*p != i) differences++;
2756 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2757 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2759 ok(differences == 0, i2 == 0 ? "Pass 1. Unexpected front buffer contents after blit (%u differences)\n" :
2760 "Pass 2 (with NULL front buffer palette). Unexpected front buffer contents after blit (%u differences)\n",
2766 if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
2767 if(offscreen) IDirectDrawSurface_Release(offscreen);
2768 if(Surface1) IDirectDrawSurface_Release(Surface1);
2769 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
2770 if(window) DestroyWindow(window);
2773 static void cubemap_test(IDirect3DDevice7 *device)
2776 IDirectDraw7 *ddraw;
2777 IDirectDrawSurface7 *cubemap, *surface;
2778 D3DDEVICEDESC7 d3dcaps;
2781 DDSURFACEDESC2 ddsd;
2784 static float quad[] = {
2785 -1.0, -1.0, 0.1, 1.0, 0.0, 0.0, /* Lower left */
2786 0.0, -1.0, 0.1, 1.0, 0.0, 0.0,
2787 -1.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2788 0.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2790 0.0, -1.0, 0.1, 0.0, 1.0, 0.0, /* Lower right */
2791 1.0, -1.0, 0.1, 0.0, 1.0, 0.0,
2792 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2793 1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2795 0.0, 0.0, 0.1, 0.0, 0.0, 1.0, /* upper right */
2796 1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
2797 0.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2798 1.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2800 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, /* Upper left */
2801 0.0, 0.0, 0.1, -1.0, 0.0, 0.0,
2802 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2803 0.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2806 memset(&DDBltFx, 0, sizeof(DDBltFx));
2807 DDBltFx.dwSize = sizeof(DDBltFx);
2809 memset(&d3dcaps, 0, sizeof(d3dcaps));
2810 hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
2811 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2812 if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2814 skip("No cubemap support\n");
2818 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2819 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
2821 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2822 ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
2823 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
2824 ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
2825 IDirect3D7_Release(d3d);
2828 memset(&ddsd, 0, sizeof(ddsd));
2829 ddsd.dwSize = sizeof(ddsd);
2830 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2831 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2834 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2835 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
2836 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2837 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2838 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2839 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2840 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2842 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
2843 ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
2844 IDirectDraw7_Release(ddraw);
2847 U5(DDBltFx).dwFillColor = 0x00ff0000;
2848 hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2849 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2851 memset(&caps, 0, sizeof(caps));
2852 caps.dwCaps = DDSCAPS_TEXTURE;
2853 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
2854 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2855 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2856 U5(DDBltFx).dwFillColor = 0x0000ffff;
2857 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2858 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2860 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
2861 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2862 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2863 U5(DDBltFx).dwFillColor = 0x0000ff00;
2864 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2865 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2867 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
2868 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2869 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2870 U5(DDBltFx).dwFillColor = 0x000000ff;
2871 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2872 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2874 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2875 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2876 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2877 U5(DDBltFx).dwFillColor = 0x00ffff00;
2878 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2879 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2881 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2882 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2883 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2884 U5(DDBltFx).dwFillColor = 0x00ff00ff;
2885 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2886 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2888 hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2889 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2890 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2891 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2892 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2893 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2895 hr = IDirect3DDevice7_BeginScene(device);
2896 ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2899 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2900 if (hr == DDERR_UNSUPPORTED || hr == DDERR_NODIRECTDRAWHW)
2903 win_skip("IDirect3DDevice7_DrawPrimitive is not completely implemented, colors won't be tested\n");
2904 hr = IDirect3DDevice7_EndScene(device);
2905 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2908 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2909 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
2910 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2911 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 8 * 6, 4, 0);
2912 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2913 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 12* 6, 4, 0);
2914 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2916 hr = IDirect3DDevice7_EndScene(device);
2917 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2919 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2920 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2922 color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2923 ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2924 color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2925 ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2926 color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2927 ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2928 color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2929 ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2932 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2933 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2934 IDirectDrawSurface7_Release(cubemap);
2937 /* This test tests depth clamping / clipping behaviour:
2938 * - With software vertex processing, depth values are clamped to the
2939 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2940 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2941 * same as regular vertices here.
2942 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2943 * Normal vertices are always clipped. Pretransformed vertices are
2944 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2945 * - The viewport's MinZ/MaxZ is irrelevant for this.
2947 static void depth_clamp_test(IDirect3DDevice7 *device)
2949 struct tvertex quad1[] =
2951 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2952 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2953 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2954 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2956 struct tvertex quad2[] =
2958 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2959 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2960 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2961 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2963 struct tvertex quad3[] =
2965 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2966 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2967 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2968 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2970 struct tvertex quad4[] =
2972 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2973 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2974 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2975 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2977 struct vertex quad5[] =
2979 { -0.5f, 0.5f, 10.0f, 0xff14f914},
2980 { 0.5f, 0.5f, 10.0f, 0xff14f914},
2981 { -0.5f, -0.5f, 10.0f, 0xff14f914},
2982 { 0.5f, -0.5f, 10.0f, 0xff14f914},
2984 struct vertex quad6[] =
2986 { -1.0f, 0.5f, 10.0f, 0xfff91414},
2987 { 1.0f, 0.5f, 10.0f, 0xfff91414},
2988 { -1.0f, 0.25f, 10.0f, 0xfff91414},
2989 { 1.0f, 0.25f, 10.0f, 0xfff91414},
3003 hr = IDirect3DDevice7_SetViewport(device, &vp);
3004 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3006 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3007 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3009 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3010 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3011 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
3012 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3013 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZWRITEENABLE, TRUE);
3014 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3015 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
3016 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3018 hr = IDirect3DDevice7_BeginScene(device);
3019 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3021 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
3022 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3023 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad2, 4, 0);
3024 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3026 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3027 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3029 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad3, 4, 0);
3030 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3031 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad4, 4, 0);
3032 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3034 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3035 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3037 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad5, 4, 0);
3038 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3040 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3041 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3043 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad6, 4, 0);
3044 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3046 hr = IDirect3DDevice7_EndScene(device);
3047 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3049 color = getPixelColor(device, 75, 75);
3050 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3051 color = getPixelColor(device, 150, 150);
3052 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3053 color = getPixelColor(device, 320, 240);
3054 ok(color_match(color, 0x00002b7f, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3055 color = getPixelColor(device, 320, 330);
3056 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3057 color = getPixelColor(device, 320, 330);
3058 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3062 hr = IDirect3DDevice7_SetViewport(device, &vp);
3063 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3066 static void DX1_BackBufferFlipTest(void)
3069 IDirectDraw *DirectDraw1 = NULL;
3070 IDirectDrawSurface *Primary = NULL;
3071 IDirectDrawSurface *Backbuffer = NULL;
3076 const DWORD white = 0xffffff;
3077 const DWORD red = 0xff0000;
3078 BOOL attached = FALSE;
3080 wc.lpfnWndProc = DefWindowProc;
3081 wc.lpszClassName = "DX1_BackBufferFlipTest_wc";
3083 window = CreateWindow("DX1_BackBufferFlipTest_wc", "DX1_BackBufferFlipTest",
3084 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3086 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
3087 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
3088 if(FAILED(hr)) goto out;
3090 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3091 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
3092 if(FAILED(hr)) goto out;
3094 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
3096 /* 24 bit is fine too */
3097 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
3099 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
3104 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3105 ddsd.dwSize = sizeof(DDSURFACEDESC);
3106 ddsd.dwFlags = DDSD_CAPS;
3107 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3109 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Primary, NULL);
3110 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3112 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3113 ddsd.dwSize = sizeof(DDSURFACEDESC);
3114 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3115 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3117 ddsd.dwHeight = 480;
3118 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3119 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3120 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
3121 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
3122 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
3123 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
3125 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Backbuffer, NULL);
3126 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3127 if(FAILED(hr)) goto out;
3129 hr = IDirectDrawSurface_AddAttachedSurface(Primary, Backbuffer);
3130 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3131 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3132 if (FAILED(hr)) goto out;
3136 memset(&ddbltfx, 0, sizeof(ddbltfx));
3137 ddbltfx.dwSize = sizeof(ddbltfx);
3138 U5(ddbltfx).dwFillColor = red;
3139 hr = IDirectDrawSurface_Blt(Backbuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3140 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3142 U5(ddbltfx).dwFillColor = white;
3143 hr = IDirectDrawSurface_Blt(Primary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3144 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3147 color = getPixelColor_GDI(Primary, 5, 5);
3148 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF,
3149 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3150 GetRValue(color), GetGValue(color), GetBValue(color));
3152 color = getPixelColor_GDI(Backbuffer, 5, 5);
3153 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3154 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3155 GetRValue(color), GetGValue(color), GetBValue(color));
3157 hr = IDirectDrawSurface_Flip(Primary, NULL, DDFLIP_WAIT);
3158 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3162 color = getPixelColor_GDI(Primary, 5, 5);
3163 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3164 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3165 GetRValue(color), GetGValue(color), GetBValue(color));
3167 color = getPixelColor_GDI(Backbuffer, 5, 5);
3168 ok((GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF) ||
3169 broken(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0), /* broken driver */
3170 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3171 GetRValue(color), GetGValue(color), GetBValue(color));
3179 IDirectDrawSurface_DeleteAttachedSurface(Primary, 0, Backbuffer);
3180 IDirectDrawSurface_Release(Backbuffer);
3182 if (Primary) IDirectDrawSurface_Release(Primary);
3183 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
3184 if (window) DestroyWindow(window);
3191 if(!createObjects())
3193 skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
3197 /* Check for the reliability of the returned data */
3198 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3201 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3205 color = getPixelColor(Direct3DDevice, 1, 1);
3206 if(color !=0x00ff0000)
3208 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3212 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3215 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3219 color = getPixelColor(Direct3DDevice, 639, 479);
3220 if(color != 0x0000ddee)
3222 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3226 /* Now run the tests */
3227 blt_test(Direct3DDevice);
3228 depth_clamp_test(Direct3DDevice);
3229 lighting_test(Direct3DDevice);
3230 clear_test(Direct3DDevice);
3231 fog_test(Direct3DDevice);
3232 offscreen_test(Direct3DDevice);
3233 alpha_test(Direct3DDevice);
3234 rhw_zero_test(Direct3DDevice);
3235 cubemap_test(Direct3DDevice);
3237 releaseObjects(); /* release DX7 interfaces to test D3D1 */
3239 if(!D3D1_createObjects()) {
3240 skip("Cannot initialize D3D1, skipping\n");
3243 D3D1_TextureMapBlendTest();
3244 D3D1_ViewportClearTest();
3246 D3D1_releaseObjects();
3248 D3D3_ViewportClearTest();
3250 DX1_BackBufferFlipTest();