2 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
3 * Copyright (C) 2008 Alexander Dorofeyev
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
22 #include "wine/test.h"
27 static IDirectDraw7 *DirectDraw;
28 static IDirectDrawSurface7 *Surface;
29 static IDirectDrawSurface7 *depth_buffer;
30 static IDirect3D7 *Direct3D;
31 static IDirect3DDevice7 *Direct3DDevice;
33 static IDirectDraw *DirectDraw1;
34 static IDirectDrawSurface *Surface1;
35 static IDirect3D *Direct3D1;
36 static IDirect3DDevice *Direct3DDevice1;
37 static IDirect3DExecuteBuffer *ExecuteBuffer;
38 static IDirect3DViewport *Viewport;
40 static BOOL refdevice = FALSE;
42 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
44 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
46 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
48 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 static HRESULT WINAPI enum_z_fmt(DDPIXELFORMAT *fmt, void *ctx)
58 DDPIXELFORMAT *zfmt = ctx;
60 if(U1(*fmt).dwZBufferBitDepth > U1(*zfmt).dwZBufferBitDepth)
67 static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7 *desc, void *ctx)
70 if (IsEqualGUID(&desc->deviceGUID, &IID_IDirect3DTnLHalDevice))
73 return DDENUMRET_CANCEL;
78 static BOOL createObjects(void)
81 HMODULE hmod = GetModuleHandleA("ddraw.dll");
86 const GUID *devtype = &IID_IDirect3DHALDevice;
88 if(!hmod) return FALSE;
89 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
90 if(!pDirectDrawCreateEx) return FALSE;
92 hr = pDirectDrawCreateEx(NULL, (void **) &DirectDraw, &IID_IDirectDraw7, NULL);
93 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
94 if(!DirectDraw) goto err;
96 wc.lpfnWndProc = DefWindowProc;
97 wc.lpszClassName = "d3d7_test_wc";
99 window = CreateWindow("d3d7_test_wc", "d3d7_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
101 hr = IDirectDraw7_SetCooperativeLevel(DirectDraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
102 ok(hr == DD_OK, "IDirectDraw7_SetCooperativeLevel failed with %08x\n", hr);
103 if(FAILED(hr)) goto err;
104 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 32, 0, 0);
106 /* 24 bit is fine too */
107 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 24, 0, 0);
110 ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "IDirectDraw7_SetDisplayMode failed with %08x\n", hr);
112 /* use trace, the caller calls skip() */
113 trace("SetDisplayMode failed\n");
117 hr = IDirectDraw7_QueryInterface(DirectDraw, &IID_IDirect3D7, (void**) &Direct3D);
118 if (hr == E_NOINTERFACE) goto err;
119 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
121 /* DirectDraw Flipping behavior doesn't seem that well-defined. The reference rasterizer behaves differently
122 * than hardware implementations. Request single buffering, that seems to work everywhere
124 memset(&ddsd, 0, sizeof(ddsd));
125 ddsd.dwSize = sizeof(ddsd);
126 ddsd.dwFlags = DDSD_CAPS;
127 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
128 ddsd.dwBackBufferCount = 1;
129 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &Surface, NULL);
130 if(FAILED(hr)) goto err;
132 hr = IDirect3D7_EnumDevices(Direct3D, enum_devtype_cb, &hal_ok);
133 ok(SUCCEEDED(hr), "Failed to enumerate devices, hr %#x.\n", hr);
134 if (hal_ok) devtype = &IID_IDirect3DTnLHalDevice;
136 memset(&zfmt, 0, sizeof(zfmt));
137 hr = IDirect3D7_EnumZBufferFormats(Direct3D, devtype, enum_z_fmt, &zfmt);
138 if (FAILED(hr)) goto err;
139 if (zfmt.dwSize == 0) goto err;
141 memset(&ddsd, 0, sizeof(ddsd));
142 ddsd.dwSize = sizeof(ddsd);
143 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
144 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
145 U4(ddsd).ddpfPixelFormat = zfmt;
148 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &depth_buffer, NULL);
149 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr);
150 if (FAILED(hr)) goto err;
152 hr = IDirectDrawSurface_AddAttachedSurface(Surface, depth_buffer);
153 ok(SUCCEEDED(hr), "AddAttachedSurface failed, hr %#x.\n", hr);
154 if (FAILED(hr)) goto err;
156 hr = IDirect3D7_CreateDevice(Direct3D, devtype, Surface, &Direct3DDevice);
157 if (FAILED(hr) || !Direct3DDevice) goto err;
161 if(DirectDraw) IDirectDraw7_Release(DirectDraw);
162 if (depth_buffer) IDirectDrawSurface7_Release(depth_buffer);
163 if(Surface) IDirectDrawSurface7_Release(Surface);
164 if(Direct3D) IDirect3D7_Release(Direct3D);
165 if(Direct3DDevice) IDirect3DDevice7_Release(Direct3DDevice);
166 if(window) DestroyWindow(window);
170 static void releaseObjects(void)
172 IDirect3DDevice7_Release(Direct3DDevice);
173 IDirect3D7_Release(Direct3D);
174 IDirectDrawSurface7_Release(depth_buffer);
175 IDirectDrawSurface7_Release(Surface);
176 IDirectDraw7_Release(DirectDraw);
177 DestroyWindow(window);
180 static DWORD getPixelColor(IDirect3DDevice7 *device, UINT x, UINT y)
185 RECT rectToLock = {x, y, x+1, y+1};
186 IDirectDrawSurface7 *surf = NULL;
188 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
189 * to an offscreen surface and lock it instead of the front buffer
191 memset(&ddsd, 0, sizeof(ddsd));
192 ddsd.dwSize = sizeof(ddsd);
193 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
194 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
197 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
198 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
199 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with %08x\n", hr);
202 trace("cannot create helper surface\n");
206 memset(&ddsd, 0, sizeof(ddsd));
207 ddsd.dwSize = sizeof(ddsd);
208 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
210 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
211 ok(hr == DD_OK, "IDirectDrawSurface7_BltFast returned %08x\n", hr);
214 trace("Cannot blit\n");
219 hr = IDirectDrawSurface7_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
222 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
227 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
228 * really important for these tests
230 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
231 hr = IDirectDrawSurface7_Unlock(surf, NULL);
234 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
238 IDirectDrawSurface7_Release(surf);
242 static void set_viewport_size(IDirect3DDevice7 *device)
244 D3DVIEWPORT7 vp = {0};
247 IDirectDrawSurface7 *target;
249 hr = IDirect3DDevice7_GetRenderTarget(device, &target);
250 ok(hr == D3D_OK, "IDirect3DDevice7_GetRenderTarget returned %08x\n", hr);
252 memset(&ddsd, 0, sizeof(ddsd));
253 ddsd.dwSize = sizeof(ddsd);
254 hr = IDirectDrawSurface7_GetSurfaceDesc(target, &ddsd);
255 ok(hr == D3D_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
256 IDirectDrawSurface7_Release(target);
258 vp.dwWidth = ddsd.dwWidth;
259 vp.dwHeight = ddsd.dwHeight;
260 hr = IDirect3DDevice7_SetViewport(device, &vp);
261 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport returned %08x\n", hr);
284 static void lighting_test(IDirect3DDevice7 *device)
287 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
288 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
291 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
292 0.0f, 1.0f, 0.0f, 0.0f,
293 0.0f, 0.0f, 1.0f, 0.0f,
294 0.0f, 0.0f, 0.0f, 1.0f };
296 struct vertex unlitquad[] =
298 {-1.0f, -1.0f, 0.1f, 0xffff0000},
299 {-1.0f, 0.0f, 0.1f, 0xffff0000},
300 { 0.0f, 0.0f, 0.1f, 0xffff0000},
301 { 0.0f, -1.0f, 0.1f, 0xffff0000},
303 struct vertex litquad[] =
305 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
306 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
307 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
308 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
310 struct nvertex unlitnquad[] =
312 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
313 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
314 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
315 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
317 struct nvertex litnquad[] =
319 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
320 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
321 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
322 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
324 WORD Indices[] = {0, 1, 2, 2, 3, 0};
326 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
327 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
329 /* Setup some states that may cause issues */
330 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
331 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
332 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
333 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
334 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
335 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
336 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
337 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
338 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
339 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
340 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
341 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
342 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_STENCILENABLE, FALSE);
343 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
344 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
345 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
346 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
347 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
348 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
349 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed with %08x\n", hr);
351 hr = IDirect3DDevice7_BeginScene(device);
352 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
355 /* No lights are defined... That means, lit vertices should be entirely black */
356 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
357 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
358 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, unlitquad, 4 /* NumVerts */,
359 Indices, 6 /* Indexcount */, 0 /* flags */);
360 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
362 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
363 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
364 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, litquad, 4 /* NumVerts */,
365 Indices, 6 /* Indexcount */, 0 /* flags */);
366 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
368 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
369 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
370 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, unlitnquad, 4 /* NumVerts */,
371 Indices, 6 /* Indexcount */, 0 /* flags */);
372 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
374 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
375 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
376 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, litnquad, 4 /* NumVerts */,
377 Indices, 6 /* Indexcount */, 0 /* flags */);
378 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
380 hr = IDirect3DDevice7_EndScene(device);
381 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
384 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
385 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
386 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
387 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
388 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
389 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
390 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
391 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
393 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
394 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
397 static void clear_test(IDirect3DDevice7 *device)
399 /* Tests the correctness of clearing parameters */
405 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
406 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
408 /* Positive x, negative y */
410 U2(rect[0]).y1 = 480;
411 U3(rect[0]).x2 = 320;
412 U4(rect[0]).y2 = 240;
414 /* Positive x, positive y */
417 U3(rect[1]).x2 = 320;
418 U4(rect[1]).y2 = 240;
419 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
420 * is ignored, the positive is still cleared afterwards
422 hr = IDirect3DDevice7_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
423 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
425 /* negative x, negative y */
426 U1(rect_negneg).x1 = 640;
427 U2(rect_negneg).y1 = 240;
428 U3(rect_negneg).x2 = 320;
429 U4(rect_negneg).y2 = 0;
430 hr = IDirect3DDevice7_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
431 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
433 color = getPixelColor(device, 160, 360); /* lower left quad */
434 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
435 color = getPixelColor(device, 160, 120); /* upper left quad */
436 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
437 color = getPixelColor(device, 480, 360); /* lower right quad */
438 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
439 color = getPixelColor(device, 480, 120); /* upper right quad */
440 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
455 static void fog_test(IDirect3DDevice7 *device)
459 float start = 0.0, end = 1.0;
462 /* Gets full z based fog with linear fog, no fog with specular color */
463 struct sVertex untransformed_1[] = {
464 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
465 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
466 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
467 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
469 /* Ok, I am too lazy to deal with transform matrices */
470 struct sVertex untransformed_2[] = {
471 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
472 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
473 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
474 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
476 /* Untransformed ones. Give them a different diffuse color to make the test look
477 * nicer. It also makes making sure that they are drawn correctly easier.
479 struct sVertexT transformed_1[] = {
480 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
481 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
482 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
483 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
485 struct sVertexT transformed_2[] = {
486 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
487 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
488 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
489 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
491 WORD Indices[] = {0, 1, 2, 2, 3, 0};
493 float ident_mat[16] =
495 1.0f, 0.0f, 0.0f, 0.0f,
496 0.0f, 1.0f, 0.0f, 0.0f,
497 0.0f, 0.0f, 1.0f, 0.0f,
498 0.0f, 0.0f, 0.0f, 1.0f
500 float world_mat1[16] =
502 1.0f, 0.0f, 0.0f, 0.0f,
503 0.0f, 1.0f, 0.0f, 0.0f,
504 0.0f, 0.0f, 1.0f, 0.0f,
505 0.0f, 0.0f, -0.5f, 1.0f
507 float world_mat2[16] =
509 1.0f, 0.0f, 0.0f, 0.0f,
510 0.0f, 1.0f, 0.0f, 0.0f,
511 0.0f, 0.0f, 1.0f, 0.0f,
512 0.0f, 0.0f, 1.0f, 1.0f
516 1.0f, 0.0f, 0.0f, 0.0f,
517 0.0f, 1.0f, 0.0f, 0.0f,
518 0.0f, 0.0f, 1.0f, 0.0f,
519 0.0f, 0.0f, -1.0f, 1.0f
522 struct sVertex far_quad1[] =
524 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
525 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
526 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
527 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
529 struct sVertex far_quad2[] =
531 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
532 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
533 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
534 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
537 memset(&caps, 0, sizeof(caps));
538 hr = IDirect3DDevice7_GetCaps(device, &caps);
539 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
540 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
541 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr);
543 /* Setup initial states: No lighting, fog on, fog color */
544 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
545 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
546 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE);
547 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
548 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */);
549 ok(hr == D3D_OK, "Setting fog color returned %08x\n", hr);
551 /* First test: Both table fog and vertex fog off */
552 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
553 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
554 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
555 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
557 /* Start = 0, end = 1. Should be default, but set them */
558 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start));
559 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
560 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end));
561 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
563 if(IDirect3DDevice7_BeginScene(device) == D3D_OK)
565 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
566 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
567 untransformed_1, 4, Indices, 6, 0);
568 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
570 /* That makes it use the Z value */
571 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
572 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
573 /* Untransformed, vertex fog != none (or table fog != none):
574 * Use the Z value as input into the equation
576 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
577 untransformed_2, 4, Indices, 6, 0);
578 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
580 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
581 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
582 transformed_1, 4, Indices, 6, 0);
583 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
585 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
586 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
587 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
590 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
591 transformed_2, 4, Indices, 6, 0);
592 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
594 hr = IDirect3DDevice7_EndScene(device);
595 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
599 ok(FALSE, "BeginScene failed\n");
602 color = getPixelColor(device, 160, 360);
603 ok(color_match(color, 0x00FF0000, 1), "Untransformed vertex with no table or vertex fog has color %08x\n", color);
604 color = getPixelColor(device, 160, 120);
605 ok(color_match(color, 0x0000FF00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
606 color = getPixelColor(device, 480, 120);
607 ok(color_match(color, 0x00FFFF00, 1), "Transformed vertex with linear vertex fog has color %08x\n", color);
608 if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
610 color = getPixelColor(device, 480, 360);
611 ok(color_match(color, 0x0000FF00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
615 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
616 * The settings above result in no fogging with vertex fog
618 color = getPixelColor(device, 480, 120);
619 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
620 trace("Info: Table fog not supported by this device\n");
623 if (caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
625 /* A simple fog + non-identity world matrix test */
626 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat1);
627 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %#08x\n", hr);
629 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
630 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
631 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
632 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
634 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
635 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %#08x\n", hr);
637 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
639 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
640 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad1, 4, Indices, 6, 0);
641 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
643 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
644 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad2, 4, Indices, 6, 0);
645 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
647 hr = IDirect3DDevice7_EndScene(device);
648 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
652 ok(FALSE, "BeginScene failed\n");
655 color = getPixelColor(device, 160, 360);
656 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
657 color = getPixelColor(device, 160, 120);
658 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
660 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
661 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat2);
662 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
663 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)proj_mat);
664 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
666 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
667 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
669 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
671 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
672 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_1, 4, Indices, 6, 0);
673 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
675 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
676 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_2, 4, Indices, 6, 0);
677 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
679 hr = IDirect3DDevice7_EndScene(device);
680 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
684 ok(FALSE, "BeginScene failed\n");
687 color = getPixelColor(device, 160, 360);
688 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
689 color = getPixelColor(device, 160, 120);
690 ok(color_match(color, 0x0000ff00, 1), "Fogged out quad has color %08x\n", color);
692 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)ident_mat);
693 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
694 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)ident_mat);
695 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
699 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
702 /* Turn off the fog master switch to avoid confusing other tests */
703 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
704 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
707 static void blt_test(IDirect3DDevice7 *device)
709 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
713 memset(&ddsd, 0, sizeof(ddsd));
714 ddsd.dwSize = sizeof(ddsd);
715 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
716 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
719 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
720 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
721 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
723 /* Offscreen blits with the same source as destination */
726 RECT src_rect, dst_rect;
728 /* Blit the whole surface to itself */
729 hr = IDirectDrawSurface_Blt(offscreen, NULL, offscreen, NULL, 0, NULL);
730 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
732 /* Overlapped blit */
733 dst_rect.left = 0; dst_rect.right = 480;
734 dst_rect.top = 0; dst_rect.bottom = 480;
735 src_rect.left = 160; src_rect.right = 640;
736 src_rect.top = 0; src_rect.bottom = 480;
737 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
738 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
740 /* Overlapped blit, flip-y through source rectangle (not allowed) */
741 dst_rect.left = 0; dst_rect.right = 480;
742 dst_rect.top = 0; dst_rect.bottom = 480;
743 src_rect.left = 160; src_rect.right = 640;
744 src_rect.top = 480; src_rect.bottom = 0;
745 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
746 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface7_Blt returned %08x\n", hr);
748 /* Overlapped blit, with shrinking in x */
749 dst_rect.left = 0; dst_rect.right = 480;
750 dst_rect.top = 0; dst_rect.bottom = 480;
751 src_rect.left = 160; src_rect.right = 480;
752 src_rect.top = 0; src_rect.bottom = 480;
753 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
754 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
757 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
758 ok(hr == D3D_OK, "Unable to obtain a surface pointer to the backbuffer, hr = %08x\n", hr);
760 /* backbuffer ==> texture blits */
761 if(SUCCEEDED(hr) && offscreen)
763 RECT src_rect, dst_rect;
765 /* backbuffer ==> texture, src_rect=NULL, dst_rect=NULL, no scaling */
766 hr = IDirectDrawSurface_Blt(offscreen, NULL, backbuffer, NULL, 0, NULL);
767 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
769 /* backbuffer ==> texture, full surface blits, no scaling */
770 dst_rect.left = 0; dst_rect.right = 640;
771 dst_rect.top = 0; dst_rect.bottom = 480;
772 src_rect.left = 0; src_rect.right = 640;
773 src_rect.top = 0; src_rect.bottom = 480;
774 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
775 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
777 /* backbuffer ==> texture, flip in y-direction through source rectangle, no scaling (allowed) */
778 dst_rect.left = 0; dst_rect.right = 640;
779 dst_rect.top = 480; dst_rect.top = 0;
780 src_rect.left = 0; src_rect.right = 640;
781 src_rect.top = 0; src_rect.bottom = 480;
782 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
783 ok(hr == DD_OK, "backbuffer => texture flip-y src_rect failed with hr = %08x\n", hr);
785 /* backbuffer ==> texture, flip in x-direction through source rectangle, no scaling (not allowed) */
786 dst_rect.left = 640; dst_rect.right = 0;
787 dst_rect.top = 0; dst_rect.top = 480;
788 src_rect.left = 0; src_rect.right = 640;
789 src_rect.top = 0; src_rect.bottom = 480;
790 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
791 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x src_rect failed with hr = %08x\n", hr);
793 /* backbuffer ==> texture, flip in y-direction through destination rectangle (not allowed) */
794 dst_rect.left = 0; dst_rect.right = 640;
795 dst_rect.top = 0; dst_rect.top = 480;
796 src_rect.left = 0; src_rect.right = 640;
797 src_rect.top = 480; src_rect.bottom = 0;
798 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
799 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-y dst_rect failed with hr = %08x\n", hr);
801 /* backbuffer ==> texture, flip in x-direction through destination rectangle, no scaling (not allowed) */
802 dst_rect.left = 0; dst_rect.right = 640;
803 dst_rect.top = 0; dst_rect.top = 480;
804 src_rect.left = 640; src_rect.right = 0;
805 src_rect.top = 0; src_rect.bottom = 480;
806 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
807 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x dst_rect failed with hr = %08x\n", hr);
810 if(offscreen) IDirectDrawSurface7_Release(offscreen);
811 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
814 static void offscreen_test(IDirect3DDevice7 *device)
817 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
821 static float quad[][5] = {
822 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
823 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
824 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
825 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
828 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
829 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
831 memset(&ddsd, 0, sizeof(ddsd));
832 ddsd.dwSize = sizeof(ddsd);
833 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
834 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
837 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
838 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
839 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
844 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
845 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
850 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
851 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
852 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
853 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
854 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
855 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
856 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
857 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
858 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
859 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
862 win_skip("Tests would crash on W2K with a refdevice\n");
866 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
867 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
868 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
869 set_viewport_size(device);
870 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
871 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
873 /* Draw without textures - Should result in a white quad */
874 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
875 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
877 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
878 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
879 set_viewport_size(device);
881 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
882 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
884 /* This time with the texture */
885 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
886 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
888 IDirect3DDevice7_EndScene(device);
891 /* Center quad - should be white */
892 color = getPixelColor(device, 320, 240);
893 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
894 /* Some quad in the cleared part of the texture */
895 color = getPixelColor(device, 170, 240);
896 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
897 /* Part of the originally cleared back buffer */
898 color = getPixelColor(device, 10, 10);
899 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
901 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
902 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
903 * the offscreen rendering mode this test would succeed or fail
905 color = getPixelColor(device, 10, 470);
906 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
910 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
911 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetTexture returned %#x.\n", hr);
915 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
916 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetRenderTarget returned %#x.\n", hr);
917 IDirectDrawSurface7_Release(backbuffer);
920 IDirectDrawSurface7_Release(offscreen);
924 static void alpha_test(IDirect3DDevice7 *device)
927 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
928 DWORD color, red, green, blue;
931 struct vertex quad1[] =
933 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
934 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
935 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
936 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
938 struct vertex quad2[] =
940 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
941 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
942 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
943 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
945 static float composite_quad[][5] = {
946 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
947 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
948 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
949 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
952 /* Clear the render target with alpha = 0.5 */
953 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
954 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
956 memset(&ddsd, 0, sizeof(ddsd));
957 ddsd.dwSize = sizeof(ddsd);
958 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
961 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
962 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
963 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
964 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
965 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
966 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000ff;
967 U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
968 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
969 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
973 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
974 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
979 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
980 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
981 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
982 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
983 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
984 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
985 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
986 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
988 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
989 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
992 win_skip("Tests would crash on W2K with a refdevice\n");
996 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
998 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
999 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
1002 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
1003 * They give essentially ZERO and ONE blend factors
1005 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1006 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1007 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1008 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1009 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
1010 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1012 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
1013 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1014 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1015 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1016 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1017 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1019 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
1020 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
1021 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
1022 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
1025 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
1026 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1027 set_viewport_size(device);
1028 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
1029 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1031 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1032 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1033 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1034 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1035 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
1036 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1038 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
1039 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1040 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1041 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1042 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1043 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1045 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
1046 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr = %08x\n", hr);
1047 set_viewport_size(device);
1049 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1050 * Disable alpha blending for the final composition
1052 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
1053 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1055 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
1056 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1057 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
1058 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1059 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
1060 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1062 hr = IDirect3DDevice7_EndScene(device);
1063 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1066 color = getPixelColor(device, 160, 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 frame buffer returned color 0x%08x, expected 0x00bf4000\n", color);
1073 color = getPixelColor(device, 160, 120);
1074 red = (color & 0x00ff0000) >> 16;
1075 green = (color & 0x0000ff00) >> 8;
1076 blue = (color & 0x000000ff);
1077 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
1078 "DSTALPHA on frame buffer returned color 0x%08x, expected 0x000000ff\n", color);
1080 color = getPixelColor(device, 480, 360);
1081 red = (color & 0x00ff0000) >> 16;
1082 green = (color & 0x0000ff00) >> 8;
1083 blue = (color & 0x000000ff);
1084 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1085 "SRCALPHA on texture returned color 0x%08x, expected 0x00bf4000\n", color);
1087 color = getPixelColor(device, 480, 120);
1088 red = (color & 0x00ff0000) >> 16;
1089 green = (color & 0x0000ff00) >> 8;
1090 blue = (color & 0x000000ff);
1091 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
1092 "DSTALPHA on texture returned color 0x%08x, expected 0x00800080\n", color);
1095 if(offscreen) IDirectDrawSurface7_Release(offscreen);
1096 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
1099 static void rhw_zero_test(IDirect3DDevice7 *device)
1101 /* Test if it will render a quad correctly when vertex rhw = 0 */
1111 {0, 100, 0, 0, 0xffffffff},
1112 {0, 0, 0, 0, 0xffffffff},
1113 {100, 100, 0, 0, 0xffffffff},
1114 {100, 0, 0, 0, 0xffffffff},
1117 /* Clear to black */
1118 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
1119 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1121 hr = IDirect3DDevice7_BeginScene(device);
1122 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
1124 if (SUCCEEDED(hr)) {
1125 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
1126 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1128 hr = IDirect3DDevice7_EndScene(device);
1129 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1132 color = getPixelColor(device, 5, 5);
1133 ok(color == 0xffffff ||
1134 broken(color == 0), /* VMware */
1135 "Got color %08x, expected 00ffffff\n", color);
1137 color = getPixelColor(device, 105, 105);
1138 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1141 static BOOL D3D1_createObjects(void)
1146 D3DEXECUTEBUFFERDESC exdesc;
1147 D3DVIEWPORT vp_data;
1149 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1150 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1152 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1157 wc.lpfnWndProc = DefWindowProc;
1158 wc.lpszClassName = "texturemapblend_test_wc";
1160 window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1162 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1163 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1168 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
1170 /* 24 bit is fine too */
1171 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
1173 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1178 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1179 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1184 memset(&ddsd, 0, sizeof(ddsd));
1185 ddsd.dwSize = sizeof(ddsd);
1186 ddsd.dwFlags = DDSD_CAPS;
1187 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
1188 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1189 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1194 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
1196 trace("Creating a HAL device failed, trying Ref\n");
1197 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
1199 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
1204 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1205 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1210 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1211 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1212 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1213 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1214 vp_data.dwSize = sizeof(vp_data);
1217 vp_data.dwWidth = 640;
1218 vp_data.dwHeight = 480;
1219 vp_data.dvScaleX = 1;
1220 vp_data.dvScaleY = 1;
1221 vp_data.dvMaxX = 640;
1222 vp_data.dvMaxY = 480;
1225 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1226 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1228 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1229 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1230 exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1231 exdesc.dwBufferSize = 512;
1232 exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
1233 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
1234 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
1242 static void D3D1_releaseObjects(void)
1244 if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1245 if(Surface1) IDirectDrawSurface_Release(Surface1);
1246 if(Viewport) IDirect3DViewport_Release(Viewport);
1247 if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1248 if(Direct3D1) IDirect3D_Release(Direct3D1);
1249 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1250 if(window) DestroyWindow(window);
1253 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
1258 RECT rectToLock = {x, y, x+1, y+1};
1259 IDirectDrawSurface *surf = NULL;
1261 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
1262 * to an offscreen surface and lock it instead of the front buffer
1264 memset(&ddsd, 0, sizeof(ddsd));
1265 ddsd.dwSize = sizeof(ddsd);
1266 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1267 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
1269 ddsd.dwHeight = 480;
1270 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
1271 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
1272 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
1275 trace("cannot create helper surface\n");
1279 memset(&ddsd, 0, sizeof(ddsd));
1280 ddsd.dwSize = sizeof(ddsd);
1281 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1283 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
1284 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
1287 trace("Cannot blit\n");
1292 hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
1295 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
1300 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
1301 * really important for these tests
1303 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
1304 hr = IDirectDrawSurface_Unlock(surf, NULL);
1307 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
1311 IDirectDrawSurface_Release(surf);
1315 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
1316 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
1317 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
1318 ((D3DINSTRUCTION*)(ptr))->wCount = count;\
1319 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1321 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
1322 U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
1323 U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
1324 ptr = ((D3DSTATE*)(ptr))+1; } while (0)
1326 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
1327 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
1328 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
1329 ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1330 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1331 ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1332 ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1333 ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1334 ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1335 ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1336 ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1338 #define EXEBUF_END(ptr) do {\
1339 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1340 ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1341 ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1342 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1344 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1345 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1346 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1347 ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1348 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1349 U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1350 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1351 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1352 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1353 ptr = ((D3DTRIANGLE*)ptr)+1;\
1354 U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1355 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1356 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1357 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1358 ptr = ((D3DTRIANGLE*)(ptr))+1;\
1361 static HRESULT CALLBACK TextureFormatEnumCallback(DDSURFACEDESC *lpDDSD, void *lpContext)
1363 if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1364 *(BOOL*)lpContext = TRUE;
1367 return DDENUMRET_OK;
1370 static void D3D1_TextureMapBlendTest(void)
1374 D3DEXECUTEBUFFERDESC exdesc;
1375 D3DEXECUTEDATA exdata;
1377 RECT rect = { 0, 0, 64, 128 };
1378 DWORD color, red, blue, green;
1379 void *exe_buffer_ptr;
1381 D3DTEXTUREHANDLE htex;
1383 IDirectDrawSurface *TexSurface = NULL;
1384 IDirect3DTexture *Texture = NULL;
1385 IDirectDrawPalette *Palette = NULL;
1386 PALETTEENTRY table1[256];
1387 BOOL p8_textures_supported = FALSE;
1397 {0.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1398 {640.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1399 {640.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1400 {0.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1401 {0.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1402 {640.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1403 {640.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1404 {0.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1407 {0.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1408 {640.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1409 {640.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1410 {0.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1411 {0.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1412 {640.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1413 {640.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1414 {0.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1417 /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1418 memset (&ddsd, 0, sizeof (ddsd));
1419 ddsd.dwSize = sizeof (ddsd);
1420 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1421 ddsd.dwHeight = 128;
1423 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1424 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1425 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1426 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1427 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1428 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1429 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1430 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1431 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1432 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1434 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1438 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1440 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1442 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1446 memset(&ddbltfx, 0, sizeof(ddbltfx));
1447 ddbltfx.dwSize = sizeof(ddbltfx);
1448 U5(ddbltfx).dwFillColor = 0;
1449 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1450 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1452 U5(ddbltfx).dwFillColor = 0xff0000ff;
1453 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1454 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1455 U5(ddbltfx).dwFillColor = 0x800000ff;
1456 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1457 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1459 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1460 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1461 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1462 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1464 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1468 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1470 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1472 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1474 EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1475 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, exe_buffer_ptr);
1476 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE, FALSE, exe_buffer_ptr);
1477 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE, FALSE, exe_buffer_ptr);
1478 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE, FALSE, exe_buffer_ptr);
1479 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_NEAREST, exe_buffer_ptr);
1480 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_NEAREST, exe_buffer_ptr);
1481 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE , D3DFILL_SOLID, exe_buffer_ptr);
1482 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA, exe_buffer_ptr);
1483 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA, exe_buffer_ptr);
1484 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1485 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, exe_buffer_ptr);
1486 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1487 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1488 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1490 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1491 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1493 EXEBUF_END(exe_buffer_ptr);
1495 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1497 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1499 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1502 memset(&exdata, 0, sizeof(exdata));
1503 exdata.dwSize = sizeof(exdata);
1504 exdata.dwVertexCount = 8;
1505 exdata.dwInstructionOffset = sizeof(test1_quads);
1506 exdata.dwInstructionLength = exe_length;
1507 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1508 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1510 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1511 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1513 if (SUCCEEDED(hr)) {
1514 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1515 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1516 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1517 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1520 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1521 red = (color & 0x00ff0000) >> 16;
1522 green = (color & 0x0000ff00) >> 8;
1523 blue = (color & 0x000000ff);
1524 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1526 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1527 red = (color & 0x00ff0000) >> 16;
1528 green = (color & 0x0000ff00) >> 8;
1529 blue = (color & 0x000000ff);
1530 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1532 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1533 red = (color & 0x00ff0000) >> 16;
1534 green = (color & 0x0000ff00) >> 8;
1535 blue = (color & 0x000000ff);
1536 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1538 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1539 red = (color & 0x00ff0000) >> 16;
1540 green = (color & 0x0000ff00) >> 8;
1541 blue = (color & 0x000000ff);
1542 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1544 /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1545 if(Texture) IDirect3DTexture_Release(Texture);
1547 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1550 memset (&ddsd, 0, sizeof (ddsd));
1551 ddsd.dwSize = sizeof (ddsd);
1552 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1553 ddsd.dwHeight = 128;
1555 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1556 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1557 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1558 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1559 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1560 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1561 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1563 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1564 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1566 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1570 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1572 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1574 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1578 memset(&ddbltfx, 0, sizeof(ddbltfx));
1579 ddbltfx.dwSize = sizeof(ddbltfx);
1580 U5(ddbltfx).dwFillColor = 0;
1581 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1582 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1584 U5(ddbltfx).dwFillColor = 0xff0000ff;
1585 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1586 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1587 U5(ddbltfx).dwFillColor = 0x800000ff;
1588 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1589 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1591 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1592 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1593 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1594 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1596 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1600 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1602 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1604 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1606 EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1607 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1608 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1609 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1611 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1612 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1614 EXEBUF_END(exe_buffer_ptr);
1616 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1618 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1620 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1623 memset(&exdata, 0, sizeof(exdata));
1624 exdata.dwSize = sizeof(exdata);
1625 exdata.dwVertexCount = 8;
1626 exdata.dwInstructionOffset = sizeof(test1_quads);
1627 exdata.dwInstructionLength = exe_length;
1628 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1629 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1631 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1632 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1634 if (SUCCEEDED(hr)) {
1635 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1636 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1637 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1638 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1641 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1642 red = (color & 0x00ff0000) >> 16;
1643 green = (color & 0x0000ff00) >> 8;
1644 blue = (color & 0x000000ff);
1645 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1647 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1648 red = (color & 0x00ff0000) >> 16;
1649 green = (color & 0x0000ff00) >> 8;
1650 blue = (color & 0x000000ff);
1651 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1653 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1654 red = (color & 0x00ff0000) >> 16;
1655 green = (color & 0x0000ff00) >> 8;
1656 blue = (color & 0x000000ff);
1657 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1659 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1660 red = (color & 0x00ff0000) >> 16;
1661 green = (color & 0x0000ff00) >> 8;
1662 blue = (color & 0x000000ff);
1663 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1665 /* 3) Test RGB - should multiply color components from diffuse color and texture */
1666 if(Texture) IDirect3DTexture_Release(Texture);
1668 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1671 memset (&ddsd, 0, sizeof (ddsd));
1672 ddsd.dwSize = sizeof (ddsd);
1673 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1674 ddsd.dwHeight = 128;
1676 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1677 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1678 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1679 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1680 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1681 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1682 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1683 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1684 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1685 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1687 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1691 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1693 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1695 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1699 memset(&ddbltfx, 0, sizeof(ddbltfx));
1700 ddbltfx.dwSize = sizeof(ddbltfx);
1701 U5(ddbltfx).dwFillColor = 0;
1702 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1703 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1705 U5(ddbltfx).dwFillColor = 0x00ffffff;
1706 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1707 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1708 U5(ddbltfx).dwFillColor = 0x00ffff80;
1709 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1710 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1712 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1713 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1714 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1715 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1717 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1721 memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1723 exe_buffer_ptr = sizeof(test2_quads) + (char*)exdesc.lpData;
1725 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1727 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1728 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1729 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1730 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1731 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1733 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1734 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1736 EXEBUF_END(exe_buffer_ptr);
1738 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test2_quads);
1740 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1742 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1745 memset(&exdata, 0, sizeof(exdata));
1746 exdata.dwSize = sizeof(exdata);
1747 exdata.dwVertexCount = 8;
1748 exdata.dwInstructionOffset = sizeof(test2_quads);
1749 exdata.dwInstructionLength = exe_length;
1750 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1751 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1753 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1754 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1756 if (SUCCEEDED(hr)) {
1757 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1758 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1759 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1760 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1763 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1764 red = (color & 0x00ff0000) >> 16;
1765 green = (color & 0x0000ff00) >> 8;
1766 blue = (color & 0x000000ff);
1767 ok(red == 0xff && green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1769 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1770 red = (color & 0x00ff0000) >> 16;
1771 green = (color & 0x0000ff00) >> 8;
1772 blue = (color & 0x000000ff);
1773 ok(red == 0xff && green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1775 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1776 red = (color & 0x00ff0000) >> 16;
1777 green = (color & 0x0000ff00) >> 8;
1778 blue = (color & 0x000000ff);
1779 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1781 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1782 red = (color & 0x00ff0000) >> 16;
1783 green = (color & 0x0000ff00) >> 8;
1784 blue = (color & 0x000000ff);
1785 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1787 /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1788 if(Texture) IDirect3DTexture_Release(Texture);
1790 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1793 memset (&ddsd, 0, sizeof (ddsd));
1794 ddsd.dwSize = sizeof (ddsd);
1795 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1796 ddsd.dwHeight = 128;
1798 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1799 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1800 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1801 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
1802 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xf800;
1803 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07e0;
1804 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001f;
1806 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1807 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1809 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1813 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1815 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1817 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1821 memset(&ddbltfx, 0, sizeof(ddbltfx));
1822 ddbltfx.dwSize = sizeof(ddbltfx);
1823 U5(ddbltfx).dwFillColor = 0;
1824 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1825 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1826 U5(ddbltfx).dwFillColor = 0xf800;
1827 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1828 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1829 U5(ddbltfx).dwFillColor = 0x001f;
1830 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1831 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1833 clrKey.dwColorSpaceLowValue = 0x001f;
1834 clrKey.dwColorSpaceHighValue = 0x001f;
1835 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1836 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1838 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1839 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1840 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1841 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1843 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1847 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1849 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1851 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1853 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1854 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1855 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1856 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1857 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1859 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1860 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1862 EXEBUF_END(exe_buffer_ptr);
1864 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
1866 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1868 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1871 memset(&exdata, 0, sizeof(exdata));
1872 exdata.dwSize = sizeof(exdata);
1873 exdata.dwVertexCount = 8;
1874 exdata.dwInstructionOffset = sizeof(test1_quads);
1875 exdata.dwInstructionLength = exe_length;
1876 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1877 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1879 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1880 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
1882 if (SUCCEEDED(hr)) {
1883 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1884 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1885 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1886 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
1889 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1890 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1892 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1893 red = (color & 0x00ff0000) >> 16;
1894 green = (color & 0x0000ff00) >> 8;
1895 blue = (color & 0x000000ff);
1896 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1898 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1899 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1901 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1902 red = (color & 0x00ff0000) >> 16;
1903 green = (color & 0x0000ff00) >> 8;
1904 blue = (color & 0x000000ff);
1905 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1907 /* 5) Test alpha again, now with color keyed P8 texture */
1908 if(Texture) IDirect3DTexture_Release(Texture);
1910 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1913 hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1914 &p8_textures_supported);
1915 ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1917 if (!p8_textures_supported) {
1918 skip("device has no P8 texture support, skipping test\n");
1920 memset (&ddsd, 0, sizeof (ddsd));
1921 ddsd.dwSize = sizeof (ddsd);
1922 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1923 ddsd.dwHeight = 128;
1925 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1926 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1927 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1928 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1930 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1931 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1933 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1937 memset(table1, 0, sizeof(table1));
1938 table1[0].peBlue = 0xff;
1939 table1[1].peRed = 0xff;
1941 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1942 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1944 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1948 hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1949 ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1951 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1953 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1955 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1959 memset(&ddbltfx, 0, sizeof(ddbltfx));
1960 ddbltfx.dwSize = sizeof(ddbltfx);
1961 U5(ddbltfx).dwFillColor = 0;
1962 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1963 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1964 U5(ddbltfx).dwFillColor = 0;
1965 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1966 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1967 U5(ddbltfx).dwFillColor = 1;
1968 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1969 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1971 clrKey.dwColorSpaceLowValue = 1;
1972 clrKey.dwColorSpaceHighValue = 1;
1973 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1974 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1976 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1977 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1978 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1979 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1981 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1985 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1987 exe_buffer_ptr = sizeof(test1_quads) + (char*)exdesc.lpData;
1989 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1991 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1992 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1993 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1994 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1995 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1997 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1998 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
2000 EXEBUF_END(exe_buffer_ptr);
2002 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - sizeof(test1_quads);
2004 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
2006 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
2009 memset(&exdata, 0, sizeof(exdata));
2010 exdata.dwSize = sizeof(exdata);
2011 exdata.dwVertexCount = 8;
2012 exdata.dwInstructionOffset = sizeof(test1_quads);
2013 exdata.dwInstructionLength = exe_length;
2014 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
2015 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
2017 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2018 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
2020 if (SUCCEEDED(hr)) {
2021 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
2022 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
2023 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2024 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
2027 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2028 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2030 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
2031 red = (color & 0x00ff0000) >> 16;
2032 green = (color & 0x0000ff00) >> 8;
2033 blue = (color & 0x000000ff);
2034 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
2036 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
2037 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2039 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
2040 red = (color & 0x00ff0000) >> 16;
2041 green = (color & 0x0000ff00) >> 8;
2042 blue = (color & 0x000000ff);
2043 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
2048 if (Palette) IDirectDrawPalette_Release(Palette);
2049 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
2050 if (Texture) IDirect3DTexture_Release(Texture);
2053 static void D3D1_ViewportClearTest(void)
2056 IDirect3DMaterial *bgMaterial = NULL;
2058 D3DMATERIALHANDLE hMat;
2059 D3DVIEWPORT vp_data;
2060 IDirect3DViewport *Viewport2 = NULL;
2061 DWORD color, red, green, blue;
2063 hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
2064 ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
2069 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
2070 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
2075 hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
2076 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
2077 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
2078 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
2079 vp_data.dwSize = sizeof(vp_data);
2082 vp_data.dwWidth = 100;
2083 vp_data.dwHeight = 100;
2084 vp_data.dvScaleX = 1;
2085 vp_data.dvScaleY = 1;
2086 vp_data.dvMaxX = 100;
2087 vp_data.dvMaxY = 100;
2090 hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
2091 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
2093 memset(&mat, 0, sizeof(mat));
2094 mat.dwSize = sizeof(mat);
2095 U1(U(mat).diffuse).r = 1.0f;
2096 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2097 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2099 hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
2100 ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
2102 hr = IDirect3DViewport_SetBackground(Viewport, hMat);
2103 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2104 hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
2105 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2107 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2108 ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
2110 if (SUCCEEDED(hr)) {
2113 U1(rect).x1 = U2(rect).y1 = 0;
2117 hr = IDirect3DViewport_Clear(Viewport, 1, &rect, D3DCLEAR_TARGET);
2118 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2120 memset(&mat, 0, sizeof(mat));
2121 mat.dwSize = sizeof(mat);
2122 U3(U(mat).diffuse).b = 1.0f;
2123 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2124 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2126 hr = IDirect3DViewport_Clear(Viewport2, 1, &rect, D3DCLEAR_TARGET);
2127 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2129 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2130 ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
2133 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2134 red = (color & 0x00ff0000) >> 16;
2135 green = (color & 0x0000ff00) >> 8;
2136 blue = (color & 0x000000ff);
2137 ok((red == 0xff && green == 0 && blue == 0) ||
2138 broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
2139 "Got color %08x, expected 00ff0000\n", color);
2141 color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
2142 red = (color & 0x00ff0000) >> 16;
2143 green = (color & 0x0000ff00) >> 8;
2144 blue = (color & 0x000000ff);
2145 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
2149 if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
2150 if (Viewport2) IDirect3DViewport_Release(Viewport2);
2153 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
2157 DDSURFACEDESC2 ddsd;
2158 RECT rectToLock = {x, y, x+1, y+1};
2159 IDirectDrawSurface4 *surf = NULL;
2161 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
2162 * to an offscreen surface and lock it instead of the front buffer
2164 memset(&ddsd, 0, sizeof(ddsd));
2165 ddsd.dwSize = sizeof(ddsd);
2166 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2167 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
2169 ddsd.dwHeight = 480;
2170 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
2171 hr = IDirectDraw4_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
2172 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2175 trace("cannot create helper surface\n");
2179 memset(&ddsd, 0, sizeof(ddsd));
2180 ddsd.dwSize = sizeof(ddsd);
2181 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2183 hr = IDirectDrawSurface4_BltFast(surf, 0, 0, Surface, NULL, 0);
2184 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
2187 trace("Cannot blit\n");
2192 hr = IDirectDrawSurface4_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
2195 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
2200 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
2201 * really important for these tests
2203 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
2204 hr = IDirectDrawSurface4_Unlock(surf, NULL);
2207 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
2211 IDirectDrawSurface4_Release(surf);
2215 static void D3D3_ViewportClearTest(void)
2218 IDirectDraw *DirectDraw1 = NULL;
2219 IDirectDraw4 *DirectDraw4 = NULL;
2220 IDirectDrawSurface4 *Primary = NULL;
2221 IDirect3D3 *Direct3D3 = NULL;
2222 IDirect3DViewport3 *Viewport3 = NULL;
2223 IDirect3DViewport3 *SmallViewport3 = NULL;
2224 IDirect3DDevice3 *Direct3DDevice3 = NULL;
2226 DDSURFACEDESC2 ddsd;
2227 D3DVIEWPORT2 vp_data;
2228 DWORD color, red, green, blue;
2230 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
2231 0.0f, 1.0f, 0.0f, 0.0f,
2232 0.0f, 0.0f, 1.0f, 0.0f,
2233 0.0f, 0.0f, 0.0f, 1.0f };
2234 struct vertex quad[] =
2236 {-1.0f, -1.0f, 0.1f, 0xffffffff},
2237 {-1.0f, 1.0f, 0.1f, 0xffffffff},
2238 { 1.0f, 1.0f, 0.1f, 0xffffffff},
2239 { 1.0f, -1.0f, 0.1f, 0xffffffff},
2242 WORD Indices[] = {0, 1, 2, 2, 3, 0};
2243 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
2245 wc.lpfnWndProc = DefWindowProc;
2246 wc.lpszClassName = "D3D3_ViewportClearTest_wc";
2248 window = CreateWindow("D3D3_ViewportClearTest_wc", "D3D3_ViewportClearTest",
2249 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2251 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2252 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2253 if(FAILED(hr)) goto out;
2255 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2256 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2257 if(FAILED(hr)) goto out;
2259 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2261 /* 24 bit is fine too */
2262 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2264 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2265 if (FAILED(hr)) goto out;
2267 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void**)&DirectDraw4);
2268 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
2269 if(FAILED(hr)) goto out;
2271 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2272 ddsd.dwSize = sizeof(DDSURFACEDESC2);
2273 ddsd.dwFlags = DDSD_CAPS;
2274 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
2276 hr = IDirectDraw_CreateSurface(DirectDraw4, &ddsd, &Primary, NULL);
2277 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2278 if(FAILED(hr)) goto out;
2280 hr = IDirectDraw4_QueryInterface(DirectDraw4, &IID_IDirect3D3, (void**)&Direct3D3);
2281 ok(hr==DD_OK, "IDirectDraw4_QueryInterface returned: %08x\n", hr);
2282 if(FAILED(hr)) goto out;
2284 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DHALDevice, Primary, &Direct3DDevice3, NULL);
2286 trace("Creating a HAL device failed, trying Ref\n");
2287 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DRefDevice, Primary, &Direct3DDevice3, NULL);
2289 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
2290 if(FAILED(hr)) goto out;
2292 hr = IDirect3D3_CreateViewport(Direct3D3, &Viewport3, NULL);
2293 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2294 if(FAILED(hr)) goto out;
2296 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, Viewport3);
2297 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2299 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2300 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2301 vp_data.dwWidth = 640;
2302 vp_data.dwHeight = 480;
2303 vp_data.dvClipX = -1.0f;
2304 vp_data.dvClipWidth = 2.0f;
2305 vp_data.dvClipY = 1.0f;
2306 vp_data.dvClipHeight = 2.0f;
2307 vp_data.dvMaxZ = 1.0f;
2308 hr = IDirect3DViewport3_SetViewport2(Viewport3, &vp_data);
2309 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2311 hr = IDirect3D3_CreateViewport(Direct3D3, &SmallViewport3, NULL);
2312 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2313 if(FAILED(hr)) goto out;
2315 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, SmallViewport3);
2316 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2318 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2319 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2322 vp_data.dwWidth = 100;
2323 vp_data.dwHeight = 100;
2324 vp_data.dvClipX = -1.0f;
2325 vp_data.dvClipWidth = 2.0f;
2326 vp_data.dvClipY = 1.0f;
2327 vp_data.dvClipHeight = 2.0f;
2328 vp_data.dvMaxZ = 1.0f;
2329 hr = IDirect3DViewport3_SetViewport2(SmallViewport3, &vp_data);
2330 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2332 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2333 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2335 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
2336 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2337 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
2338 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2339 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
2340 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2341 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CLIPPING, FALSE);
2342 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2343 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ZENABLE, FALSE);
2344 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2345 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_FOGENABLE, FALSE);
2346 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2347 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_STENCILENABLE, FALSE);
2348 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2349 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
2350 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2351 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
2352 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2353 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
2354 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState failed with %08x\n", hr);
2355 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
2356 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2358 if (SUCCEEDED(hr)) {
2359 U1(rect).x1 = U2(rect).y1 = 0;
2363 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x00ff00, 0.0f, 0);
2364 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2366 hr = IDirect3DViewport3_Clear2(SmallViewport3, 1, &rect, D3DCLEAR_TARGET, 0xff0000, 0.0f, 0);
2367 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2369 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2370 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2373 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2374 red = (color & 0x00ff0000) >> 16;
2375 green = (color & 0x0000ff00) >> 8;
2376 blue = (color & 0x000000ff);
2377 ok(red == 0 && green == 0xff && blue == 0, "Got color %08x, expected 0000ff00\n", color);
2379 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2380 red = (color & 0x00ff0000) >> 16;
2381 green = (color & 0x0000ff00) >> 8;
2382 blue = (color & 0x000000ff);
2383 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000\n", color);
2385 /* Test that clearing viewport doesn't interfere with rendering to previously active viewport. */
2386 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2387 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2389 if (SUCCEEDED(hr)) {
2390 hr = IDirect3DDevice3_SetCurrentViewport(Direct3DDevice3, SmallViewport3);
2391 ok(hr == D3D_OK, "IDirect3DDevice3_SetCurrentViewport failed with %08x\n", hr);
2393 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x000000, 0.0f, 0);
2394 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2396 hr = IDirect3DDevice3_DrawIndexedPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf, quad, 4 /* NumVerts */,
2397 Indices, 6 /* Indexcount */, 0 /* flags */);
2398 ok(hr == D3D_OK, "IDirect3DDevice3_DrawIndexedPrimitive failed with %08x\n", hr);
2400 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2401 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2404 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2405 red = (color & 0x00ff0000) >> 16;
2406 green = (color & 0x0000ff00) >> 8;
2407 blue = (color & 0x000000ff);
2408 ok(red == 0 && green == 0 && blue == 0, "Got color %08x, expected 00000000\n", color);
2410 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2411 red = (color & 0x00ff0000) >> 16;
2412 green = (color & 0x0000ff00) >> 8;
2413 blue = (color & 0x000000ff);
2414 ok(red == 0xff && green == 0xff && blue == 0xff, "Got color %08x, expected 00ffffff\n", color);
2418 if (SmallViewport3) IDirect3DViewport3_Release(SmallViewport3);
2419 if (Viewport3) IDirect3DViewport3_Release(Viewport3);
2420 if (Direct3DDevice3) IDirect3DDevice3_Release(Direct3DDevice3);
2421 if (Direct3D3) IDirect3D3_Release(Direct3D3);
2422 if (Primary) IDirectDrawSurface4_Release(Primary);
2423 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
2424 if (DirectDraw4) IDirectDraw4_Release(DirectDraw4);
2425 if(window) DestroyWindow(window);
2428 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
2435 memset(&ddsd, 0, sizeof(ddsd));
2436 ddsd.dwSize = sizeof(ddsd);
2438 hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
2439 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2441 p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2443 for (i = 0; i < h; i++) {
2444 for (i1 = 0; i1 < w; i1++) {
2447 p += U1(ddsd).lPitch;
2450 hr = IDirectDrawSurface_Unlock(dest, NULL);
2451 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2454 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
2456 COLORREF clr = CLR_INVALID;
2460 hr = IDirectDrawSurface_GetDC(Surface, &hdc);
2461 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2463 if (SUCCEEDED(hr)) {
2464 clr = GetPixel(hdc, x, y);
2466 hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
2467 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2473 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
2477 for (i = 0; i < 256; i++) {
2478 if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
2479 table1[i].peBlue != table2[i].rgbBlue) return FALSE;
2485 static void p8_primary_test(void)
2487 /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
2491 PALETTEENTRY entries[256];
2492 RGBQUAD coltable[256];
2494 IDirectDrawPalette *ddprimpal = NULL;
2495 IDirectDrawSurface *offscreen = NULL;
2501 unsigned differences;
2503 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
2504 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
2506 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2511 wc.lpfnWndProc = DefWindowProc;
2512 wc.lpszClassName = "p8_primary_test_wc";
2514 window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2516 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2517 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2522 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
2523 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2528 memset(&ddsd, 0, sizeof(ddsd));
2529 ddsd.dwSize = sizeof(ddsd);
2530 ddsd.dwFlags = DDSD_CAPS;
2531 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2532 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
2533 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
2538 memset(entries, 0, sizeof(entries));
2539 entries[0].peRed = 0xff;
2540 entries[1].peGreen = 0xff;
2541 entries[2].peBlue = 0xff;
2543 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
2544 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2546 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
2550 hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
2551 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2553 p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
2555 color = getPixelColor_GDI(Surface1, 10, 10);
2556 ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
2557 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2558 GetRValue(color), GetGValue(color), GetBValue(color));
2560 memset(&ddbltfx, 0, sizeof(ddbltfx));
2561 ddbltfx.dwSize = sizeof(ddbltfx);
2562 U5(ddbltfx).dwFillColor = 0;
2563 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2564 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2566 color = getPixelColor_GDI(Surface1, 10, 10);
2567 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
2568 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
2569 GetRValue(color), GetGValue(color), GetBValue(color));
2571 memset(&ddbltfx, 0, sizeof(ddbltfx));
2572 ddbltfx.dwSize = sizeof(ddbltfx);
2573 U5(ddbltfx).dwFillColor = 1;
2574 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2575 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2577 color = getPixelColor_GDI(Surface1, 10, 10);
2578 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2579 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2580 GetRValue(color), GetGValue(color), GetBValue(color));
2582 memset (&ddsd, 0, sizeof (ddsd));
2583 ddsd.dwSize = sizeof (ddsd);
2584 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2587 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
2588 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2589 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2590 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2591 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2593 broken(hr == DDERR_INVALIDPIXELFORMAT) || /* VMware */
2594 broken(hr == DDERR_NODIRECTDRAWHW), /* VMware */
2595 "IDirectDraw_CreateSurface returned %08x\n", hr);
2596 if (FAILED(hr)) goto out;
2598 memset(entries, 0, sizeof(entries));
2599 for (i = 0; i < 256; i++) {
2600 entries[i].peBlue = i;
2602 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2603 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2605 hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
2606 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2607 i = GetDIBColorTable(hdc, 0, 256, coltable);
2608 ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
2609 hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
2610 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2612 ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
2614 p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 2);
2616 memset(entries, 0, sizeof(entries));
2617 entries[0].peRed = 0xff;
2618 entries[1].peGreen = 0xff;
2619 entries[2].peBlue = 0xff;
2620 entries[3].peRed = 0x80;
2621 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2622 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2624 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2625 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2627 color = getPixelColor_GDI(Surface1, 1, 1);
2628 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2629 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2630 GetRValue(color), GetGValue(color), GetBValue(color));
2632 /* Color keyed blit. */
2633 p8_surface_fill_rect(offscreen, 0, 0, 8, 8, 3);
2634 clrKey.dwColorSpaceLowValue = 3;
2635 clrKey.dwColorSpaceHighValue = 3;
2636 hr = IDirectDrawSurface_SetColorKey(offscreen, DDCKEY_SRCBLT, &clrKey);
2637 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
2639 hr = IDirectDrawSurface_BltFast(Surface1, 100, 100, offscreen, NULL, DDBLTFAST_SRCCOLORKEY);
2640 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2642 color = getPixelColor_GDI(Surface1, 105, 105);
2643 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2644 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2645 GetRValue(color), GetGValue(color), GetBValue(color));
2647 color = getPixelColor_GDI(Surface1, 112, 112);
2648 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2649 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2650 GetRValue(color), GetGValue(color), GetBValue(color));
2657 memset(&ddbltfx, 0, sizeof(ddbltfx));
2658 ddbltfx.dwSize = sizeof(ddbltfx);
2659 ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 2;
2660 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2661 DDBLT_WAIT | DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2662 ok(hr==DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned: %x\n", hr);
2663 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2664 DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2665 ok(hr==DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2667 color = getPixelColor_GDI(Surface1, 105, 205);
2668 ok(GetRValue(color) == 0x80 && GetGValue(color) == 0 && GetBValue(color) == 0,
2669 "got R %02X G %02X B %02X, expected R 80 G 00 B 00\n",
2670 GetRValue(color), GetGValue(color), GetBValue(color));
2672 color = getPixelColor_GDI(Surface1, 112, 212);
2673 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2674 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2675 GetRValue(color), GetGValue(color), GetBValue(color));
2677 /* Test blitting and locking patterns that are likely to trigger bugs in opengl renderer (p8
2678 surface conversion and uploading/downloading to/from opengl texture). Similar patterns (
2679 blitting front buffer areas to/from an offscreen surface mixed with locking) are used by C&C
2681 IDirectDrawSurface_Release(offscreen);
2683 memset (&ddsd, 0, sizeof (ddsd));
2684 ddsd.dwSize = sizeof (ddsd);
2685 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2687 ddsd.dwHeight = 480;
2688 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2689 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2690 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2691 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2692 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2693 ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
2695 if (FAILED(hr)) goto out;
2697 /* Test two times, first time front buffer has a palette and second time front buffer
2698 has no palette; the latter is somewhat contrived example, but an app could set
2699 front buffer palette later. */
2700 for (i2 = 0; i2 < 2; i2++) {
2702 hr = IDirectDrawSurface_SetPalette(Surface1, NULL);
2703 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2706 memset(&ddsd, 0, sizeof(ddsd));
2707 ddsd.dwSize = sizeof(ddsd);
2708 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2709 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2711 for (i = 0; i < 256; i++) {
2712 unsigned x = (i % 128) * 4;
2713 unsigned y = (i / 128) * 4;
2714 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2716 for (i1 = 0; i1 < 4; i1++) {
2717 p[0] = p[1] = p[2] = p[3] = i;
2718 p += U1(ddsd).lPitch;
2722 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2723 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2725 hr = IDirectDrawSurface_BltFast(offscreen, 0, 0, Surface1, NULL, 0);
2726 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2728 /* This ensures offscreen surface contents will be downloaded to system memory. */
2729 memset(&ddsd, 0, sizeof(ddsd));
2730 ddsd.dwSize = sizeof(ddsd);
2731 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2732 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2733 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2734 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2736 /* Offscreen surface data will have to be converted and uploaded to texture. */
2741 hr = IDirectDrawSurface_BltFast(offscreen, 600, 400, Surface1, &rect, 0);
2742 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2744 /* This ensures offscreen surface contents will be downloaded to system memory. */
2745 memset(&ddsd, 0, sizeof(ddsd));
2746 ddsd.dwSize = sizeof(ddsd);
2747 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2748 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2749 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2750 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2752 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2753 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2755 memset(&ddsd, 0, sizeof(ddsd));
2756 ddsd.dwSize = sizeof(ddsd);
2757 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2758 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2762 for (i = 0; i < 256; i++) {
2763 unsigned x = (i % 128) * 4 + 1;
2764 unsigned y = (i / 128) * 4 + 1;
2765 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2767 if (*p != i) differences++;
2770 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2771 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2773 ok(differences == 0, i2 == 0 ? "Pass 1. Unexpected front buffer contents after blit (%u differences)\n" :
2774 "Pass 2 (with NULL front buffer palette). Unexpected front buffer contents after blit (%u differences)\n",
2780 if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
2781 if(offscreen) IDirectDrawSurface_Release(offscreen);
2782 if(Surface1) IDirectDrawSurface_Release(Surface1);
2783 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
2784 if(window) DestroyWindow(window);
2787 static void cubemap_test(IDirect3DDevice7 *device)
2790 IDirectDraw7 *ddraw;
2791 IDirectDrawSurface7 *cubemap, *surface;
2792 D3DDEVICEDESC7 d3dcaps;
2795 DDSURFACEDESC2 ddsd;
2798 static float quad[] = {
2799 -1.0, -1.0, 0.1, 1.0, 0.0, 0.0, /* Lower left */
2800 0.0, -1.0, 0.1, 1.0, 0.0, 0.0,
2801 -1.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2802 0.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2804 0.0, -1.0, 0.1, 0.0, 1.0, 0.0, /* Lower right */
2805 1.0, -1.0, 0.1, 0.0, 1.0, 0.0,
2806 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2807 1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2809 0.0, 0.0, 0.1, 0.0, 0.0, 1.0, /* upper right */
2810 1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
2811 0.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2812 1.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2814 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, /* Upper left */
2815 0.0, 0.0, 0.1, -1.0, 0.0, 0.0,
2816 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2817 0.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2820 memset(&DDBltFx, 0, sizeof(DDBltFx));
2821 DDBltFx.dwSize = sizeof(DDBltFx);
2823 memset(&d3dcaps, 0, sizeof(d3dcaps));
2824 hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
2825 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2826 if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2828 skip("No cubemap support\n");
2832 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2833 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
2835 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2836 ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
2837 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
2838 ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
2839 IDirect3D7_Release(d3d);
2842 memset(&ddsd, 0, sizeof(ddsd));
2843 ddsd.dwSize = sizeof(ddsd);
2844 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2845 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2848 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2849 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
2850 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2851 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2852 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2853 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2854 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2856 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
2857 ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
2858 IDirectDraw7_Release(ddraw);
2861 U5(DDBltFx).dwFillColor = 0x00ff0000;
2862 hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2863 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2865 memset(&caps, 0, sizeof(caps));
2866 caps.dwCaps = DDSCAPS_TEXTURE;
2867 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
2868 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2869 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2870 U5(DDBltFx).dwFillColor = 0x0000ffff;
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_NEGATIVEZ;
2875 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2876 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2877 U5(DDBltFx).dwFillColor = 0x0000ff00;
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_POSITIVEZ;
2882 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2883 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2884 U5(DDBltFx).dwFillColor = 0x000000ff;
2885 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2886 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2888 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2889 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2890 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2891 U5(DDBltFx).dwFillColor = 0x00ffff00;
2892 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2893 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2895 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2896 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2897 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2898 U5(DDBltFx).dwFillColor = 0x00ff00ff;
2899 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2900 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2902 hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2903 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2904 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2905 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2906 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2907 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2909 hr = IDirect3DDevice7_BeginScene(device);
2910 ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2913 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2914 if (hr == DDERR_UNSUPPORTED || hr == DDERR_NODIRECTDRAWHW)
2917 win_skip("IDirect3DDevice7_DrawPrimitive is not completely implemented, colors won't be tested\n");
2918 hr = IDirect3DDevice7_EndScene(device);
2919 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2922 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2923 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
2924 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2925 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 8 * 6, 4, 0);
2926 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2927 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 12* 6, 4, 0);
2928 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2930 hr = IDirect3DDevice7_EndScene(device);
2931 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2933 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2934 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2936 color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2937 ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2938 color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2939 ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2940 color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2941 ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2942 color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2943 ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2946 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2947 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2948 IDirectDrawSurface7_Release(cubemap);
2951 /* This test tests depth clamping / clipping behaviour:
2952 * - With software vertex processing, depth values are clamped to the
2953 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2954 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2955 * same as regular vertices here.
2956 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2957 * Normal vertices are always clipped. Pretransformed vertices are
2958 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2959 * - The viewport's MinZ/MaxZ is irrelevant for this.
2961 static void depth_clamp_test(IDirect3DDevice7 *device)
2963 struct tvertex quad1[] =
2965 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2966 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2967 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2968 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2970 struct tvertex quad2[] =
2972 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2973 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2974 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2975 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2977 struct tvertex quad3[] =
2979 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2980 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2981 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2982 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2984 struct tvertex quad4[] =
2986 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2987 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2988 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2989 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2991 struct vertex quad5[] =
2993 { -0.5f, 0.5f, 10.0f, 0xff14f914},
2994 { 0.5f, 0.5f, 10.0f, 0xff14f914},
2995 { -0.5f, -0.5f, 10.0f, 0xff14f914},
2996 { 0.5f, -0.5f, 10.0f, 0xff14f914},
2998 struct vertex quad6[] =
3000 { -1.0f, 0.5f, 10.0f, 0xfff91414},
3001 { 1.0f, 0.5f, 10.0f, 0xfff91414},
3002 { -1.0f, 0.25f, 10.0f, 0xfff91414},
3003 { 1.0f, 0.25f, 10.0f, 0xfff91414},
3017 hr = IDirect3DDevice7_SetViewport(device, &vp);
3018 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3020 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3021 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3023 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3024 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3025 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
3026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3027 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZWRITEENABLE, TRUE);
3028 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3029 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
3030 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3032 hr = IDirect3DDevice7_BeginScene(device);
3033 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3035 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
3036 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3037 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad2, 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_XYZRHW | D3DFVF_DIFFUSE, quad3, 4, 0);
3044 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3045 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad4, 4, 0);
3046 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3048 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3049 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3051 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad5, 4, 0);
3052 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3054 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3057 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad6, 4, 0);
3058 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3060 hr = IDirect3DDevice7_EndScene(device);
3061 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3063 color = getPixelColor(device, 75, 75);
3064 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3065 color = getPixelColor(device, 150, 150);
3066 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3067 color = getPixelColor(device, 320, 240);
3068 ok(color_match(color, 0x00002b7f, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3069 color = getPixelColor(device, 320, 330);
3070 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3071 color = getPixelColor(device, 320, 330);
3072 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3076 hr = IDirect3DDevice7_SetViewport(device, &vp);
3077 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3080 static void DX1_BackBufferFlipTest(void)
3083 IDirectDraw *DirectDraw1 = NULL;
3084 IDirectDrawSurface *Primary = NULL;
3085 IDirectDrawSurface *Backbuffer = NULL;
3090 const DWORD white = 0xffffff;
3091 const DWORD red = 0xff0000;
3092 BOOL attached = FALSE;
3094 wc.lpfnWndProc = DefWindowProc;
3095 wc.lpszClassName = "DX1_BackBufferFlipTest_wc";
3097 window = CreateWindow("DX1_BackBufferFlipTest_wc", "DX1_BackBufferFlipTest",
3098 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3100 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
3101 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
3102 if(FAILED(hr)) goto out;
3104 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3105 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
3106 if(FAILED(hr)) goto out;
3108 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
3110 /* 24 bit is fine too */
3111 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
3113 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
3118 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3119 ddsd.dwSize = sizeof(DDSURFACEDESC);
3120 ddsd.dwFlags = DDSD_CAPS;
3121 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3123 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Primary, NULL);
3124 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3126 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3127 ddsd.dwSize = sizeof(DDSURFACEDESC);
3128 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3129 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3131 ddsd.dwHeight = 480;
3132 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3133 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3134 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
3135 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
3136 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
3137 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
3139 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Backbuffer, NULL);
3140 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3141 if(FAILED(hr)) goto out;
3143 hr = IDirectDrawSurface_AddAttachedSurface(Primary, Backbuffer);
3144 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3145 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3146 if (FAILED(hr)) goto out;
3150 memset(&ddbltfx, 0, sizeof(ddbltfx));
3151 ddbltfx.dwSize = sizeof(ddbltfx);
3152 U5(ddbltfx).dwFillColor = red;
3153 hr = IDirectDrawSurface_Blt(Backbuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3154 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3156 U5(ddbltfx).dwFillColor = white;
3157 hr = IDirectDrawSurface_Blt(Primary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3158 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3161 color = getPixelColor_GDI(Primary, 5, 5);
3162 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF,
3163 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3164 GetRValue(color), GetGValue(color), GetBValue(color));
3166 color = getPixelColor_GDI(Backbuffer, 5, 5);
3167 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3168 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3169 GetRValue(color), GetGValue(color), GetBValue(color));
3171 hr = IDirectDrawSurface_Flip(Primary, NULL, DDFLIP_WAIT);
3172 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3176 color = getPixelColor_GDI(Primary, 5, 5);
3177 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3178 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3179 GetRValue(color), GetGValue(color), GetBValue(color));
3181 color = getPixelColor_GDI(Backbuffer, 5, 5);
3182 ok((GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF) ||
3183 broken(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0), /* broken driver */
3184 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3185 GetRValue(color), GetGValue(color), GetBValue(color));
3193 IDirectDrawSurface_DeleteAttachedSurface(Primary, 0, Backbuffer);
3194 IDirectDrawSurface_Release(Backbuffer);
3196 if (Primary) IDirectDrawSurface_Release(Primary);
3197 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
3198 if (window) DestroyWindow(window);
3205 if(!createObjects())
3207 skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
3211 /* Check for the reliability of the returned data */
3212 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3215 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3219 color = getPixelColor(Direct3DDevice, 1, 1);
3220 if(color !=0x00ff0000)
3222 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3226 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3229 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3233 color = getPixelColor(Direct3DDevice, 639, 479);
3234 if(color != 0x0000ddee)
3236 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3240 /* Now run the tests */
3241 blt_test(Direct3DDevice);
3242 depth_clamp_test(Direct3DDevice);
3243 lighting_test(Direct3DDevice);
3244 clear_test(Direct3DDevice);
3245 fog_test(Direct3DDevice);
3246 offscreen_test(Direct3DDevice);
3247 alpha_test(Direct3DDevice);
3248 rhw_zero_test(Direct3DDevice);
3249 cubemap_test(Direct3DDevice);
3251 releaseObjects(); /* release DX7 interfaces to test D3D1 */
3253 if(!D3D1_createObjects()) {
3254 skip("Cannot initialize D3D1, skipping\n");
3257 D3D1_TextureMapBlendTest();
3258 D3D1_ViewportClearTest();
3260 D3D1_releaseObjects();
3262 D3D3_ViewportClearTest();
3264 DX1_BackBufferFlipTest();