2 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
3 * Copyright (C) 2008 Alexander Dorofeyev
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
23 #include "wine/test.h"
28 static IDirectDraw7 *DirectDraw;
29 static IDirectDrawSurface7 *Surface;
30 static IDirectDrawSurface7 *depth_buffer;
31 static IDirect3D7 *Direct3D;
32 static IDirect3DDevice7 *Direct3DDevice;
34 static IDirectDraw *DirectDraw1;
35 static IDirectDrawSurface *Surface1;
36 static IDirect3D *Direct3D1;
37 static IDirect3DDevice *Direct3DDevice1;
38 static IDirect3DExecuteBuffer *ExecuteBuffer;
39 static IDirect3DViewport *Viewport;
41 static BOOL refdevice = FALSE;
43 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
45 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
47 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
49 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
51 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 static BOOL createObjects(void)
60 HMODULE hmod = GetModuleHandleA("ddraw.dll");
65 if(!hmod) return FALSE;
66 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
67 if(!pDirectDrawCreateEx) return FALSE;
69 hr = pDirectDrawCreateEx(NULL, (void **) &DirectDraw, &IID_IDirectDraw7, NULL);
70 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
71 if(!DirectDraw) goto err;
73 wc.lpfnWndProc = DefWindowProc;
74 wc.lpszClassName = "d3d7_test_wc";
76 window = CreateWindow("d3d7_test_wc", "d3d7_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
78 hr = IDirectDraw7_SetCooperativeLevel(DirectDraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
79 ok(hr == DD_OK, "IDirectDraw7_SetCooperativeLevel failed with %08x\n", hr);
80 if(FAILED(hr)) goto err;
81 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 32, 0, 0);
83 /* 24 bit is fine too */
84 hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 24, 0, 0);
87 ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "IDirectDraw7_SetDisplayMode failed with %08x\n", hr);
89 /* use trace, the caller calls skip() */
90 trace("SetDisplayMode failed\n");
94 hr = IDirectDraw7_QueryInterface(DirectDraw, &IID_IDirect3D7, (void**) &Direct3D);
95 if (hr == E_NOINTERFACE) goto err;
96 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
98 /* DirectDraw Flipping behavior doesn't seem that well-defined. The reference rasterizer behaves differently
99 * than hardware implementations. Request single buffering, that seems to work everywhere
101 memset(&ddsd, 0, sizeof(ddsd));
102 ddsd.dwSize = sizeof(ddsd);
103 ddsd.dwFlags = DDSD_CAPS;
104 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
105 ddsd.dwBackBufferCount = 1;
106 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &Surface, NULL);
107 if(FAILED(hr)) goto err;
109 memset(&ddsd, 0, sizeof(ddsd));
110 ddsd.dwSize = sizeof(ddsd);
111 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
112 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
113 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
114 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
115 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 32;
116 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x00ffffff;
119 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &depth_buffer, NULL);
120 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr);
121 if (FAILED(hr)) goto err;
123 hr = IDirectDrawSurface_AddAttachedSurface(Surface, depth_buffer);
124 ok(SUCCEEDED(hr), "AddAttachedSurface failed, hr %#x.\n", hr);
125 if (FAILED(hr)) goto err;
127 hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DTnLHalDevice, Surface, &Direct3DDevice);
128 if (FAILED(hr) || !Direct3DDevice) goto err;
132 if(DirectDraw) IDirectDraw7_Release(DirectDraw);
133 if (depth_buffer) IDirectDrawSurface7_Release(depth_buffer);
134 if(Surface) IDirectDrawSurface7_Release(Surface);
135 if(Direct3D) IDirect3D7_Release(Direct3D);
136 if(Direct3DDevice) IDirect3DDevice7_Release(Direct3DDevice);
137 if(window) DestroyWindow(window);
141 static void releaseObjects(void)
143 IDirect3DDevice7_Release(Direct3DDevice);
144 IDirect3D7_Release(Direct3D);
145 IDirectDrawSurface7_Release(depth_buffer);
146 IDirectDrawSurface7_Release(Surface);
147 IDirectDraw7_Release(DirectDraw);
148 DestroyWindow(window);
151 static DWORD getPixelColor(IDirect3DDevice7 *device, UINT x, UINT y)
156 RECT rectToLock = {x, y, x+1, y+1};
157 IDirectDrawSurface7 *surf = NULL;
159 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
160 * to an offscreen surface and lock it instead of the front buffer
162 memset(&ddsd, 0, sizeof(ddsd));
163 ddsd.dwSize = sizeof(ddsd);
164 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
165 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
168 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
169 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
170 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with %08x\n", hr);
173 trace("cannot create helper surface\n");
177 memset(&ddsd, 0, sizeof(ddsd));
178 ddsd.dwSize = sizeof(ddsd);
179 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
181 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
182 ok(hr == DD_OK, "IDirectDrawSurface7_BltFast returned %08x\n", hr);
185 trace("Cannot blit\n");
190 hr = IDirectDrawSurface7_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
193 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
198 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
199 * really important for these tests
201 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
202 hr = IDirectDrawSurface7_Unlock(surf, NULL);
205 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
209 IDirectDrawSurface7_Release(surf);
214 * Helper function to get and set the viewport - needed on geforce 8800 on XP - driver bug?
215 * This is needed after IDirect3DDevice7_SetRenderTarget in combination with offscreen to backbuffer rendering.
217 static void set_the_same_viewport_again(IDirect3DDevice7 *device)
219 D3DVIEWPORT7 vp = {0};
221 hr = IDirect3DDevice7_GetViewport(device,&vp);
222 ok(hr == D3D_OK && vp.dwWidth == 640 && vp.dwHeight == 480, "IDirect3DDevice7_SetViewport returned %08x\n", hr);
223 hr = IDirect3DDevice7_SetViewport(device, &vp);
224 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport returned %08x\n", hr);
247 static void lighting_test(IDirect3DDevice7 *device)
250 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
251 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
254 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
255 0.0f, 1.0f, 0.0f, 0.0f,
256 0.0f, 0.0f, 1.0f, 0.0f,
257 0.0f, 0.0f, 0.0f, 1.0f };
259 struct vertex unlitquad[] =
261 {-1.0f, -1.0f, 0.1f, 0xffff0000},
262 {-1.0f, 0.0f, 0.1f, 0xffff0000},
263 { 0.0f, 0.0f, 0.1f, 0xffff0000},
264 { 0.0f, -1.0f, 0.1f, 0xffff0000},
266 struct vertex litquad[] =
268 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
269 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
270 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
271 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
273 struct nvertex unlitnquad[] =
275 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
276 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
277 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
278 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
280 struct nvertex litnquad[] =
282 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
283 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
284 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
285 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
287 WORD Indices[] = {0, 1, 2, 2, 3, 0};
289 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
290 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
292 /* Setup some states that may cause issues */
293 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
294 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
295 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
296 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
297 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
298 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
299 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
300 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
301 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
302 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
303 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
304 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
305 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_STENCILENABLE, FALSE);
306 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
307 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
308 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
309 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
310 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
311 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
312 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed with %08x\n", hr);
314 hr = IDirect3DDevice7_BeginScene(device);
315 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
318 /* No lights are defined... That means, lit vertices should be entirely black */
319 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
320 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
321 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, unlitquad, 4 /* NumVerts */,
322 Indices, 6 /* Indexcount */, 0 /* flags */);
323 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
325 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
326 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
327 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, litquad, 4 /* NumVerts */,
328 Indices, 6 /* Indexcount */, 0 /* flags */);
329 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
331 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
332 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
333 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, unlitnquad, 4 /* NumVerts */,
334 Indices, 6 /* Indexcount */, 0 /* flags */);
335 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
337 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
338 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
339 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, litnquad, 4 /* NumVerts */,
340 Indices, 6 /* Indexcount */, 0 /* flags */);
341 ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
343 IDirect3DDevice7_EndScene(device);
344 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
347 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
348 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
349 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
350 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
351 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
352 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
353 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
354 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
356 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
357 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
360 static void clear_test(IDirect3DDevice7 *device)
362 /* Tests the correctness of clearing parameters */
368 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
369 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
371 /* Positive x, negative y */
373 U2(rect[0]).y1 = 480;
374 U3(rect[0]).x2 = 320;
375 U4(rect[0]).y2 = 240;
377 /* Positive x, positive y */
380 U3(rect[1]).x2 = 320;
381 U4(rect[1]).y2 = 240;
382 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
383 * is ignored, the positive is still cleared afterwards
385 hr = IDirect3DDevice7_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
386 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
388 /* negative x, negative y */
389 U1(rect_negneg).x1 = 640;
390 U2(rect_negneg).y1 = 240;
391 U3(rect_negneg).x2 = 320;
392 U4(rect_negneg).y2 = 0;
393 hr = IDirect3DDevice7_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
394 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
396 color = getPixelColor(device, 160, 360); /* lower left quad */
397 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
398 color = getPixelColor(device, 160, 120); /* upper left quad */
399 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
400 color = getPixelColor(device, 480, 360); /* lower right quad */
401 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
402 color = getPixelColor(device, 480, 120); /* upper right quad */
403 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
418 static void fog_test(IDirect3DDevice7 *device)
422 float start = 0.0, end = 1.0;
425 /* Gets full z based fog with linear fog, no fog with specular color */
426 struct sVertex untransformed_1[] = {
427 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
428 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
429 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
430 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
432 /* Ok, I am too lazy to deal with transform matrices */
433 struct sVertex untransformed_2[] = {
434 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
435 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
436 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
437 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
439 /* Untransformed ones. Give them a different diffuse color to make the test look
440 * nicer. It also makes making sure that they are drawn correctly easier.
442 struct sVertexT transformed_1[] = {
443 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
444 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
445 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
446 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
448 struct sVertexT transformed_2[] = {
449 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
450 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
451 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
452 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
454 WORD Indices[] = {0, 1, 2, 2, 3, 0};
456 float ident_mat[16] =
458 1.0f, 0.0f, 0.0f, 0.0f,
459 0.0f, 1.0f, 0.0f, 0.0f,
460 0.0f, 0.0f, 1.0f, 0.0f,
461 0.0f, 0.0f, 0.0f, 1.0f
463 float world_mat1[16] =
465 1.0f, 0.0f, 0.0f, 0.0f,
466 0.0f, 1.0f, 0.0f, 0.0f,
467 0.0f, 0.0f, 1.0f, 0.0f,
468 0.0f, 0.0f, -0.5f, 1.0f
470 float world_mat2[16] =
472 1.0f, 0.0f, 0.0f, 0.0f,
473 0.0f, 1.0f, 0.0f, 0.0f,
474 0.0f, 0.0f, 1.0f, 0.0f,
475 0.0f, 0.0f, 1.0f, 1.0f
479 1.0f, 0.0f, 0.0f, 0.0f,
480 0.0f, 1.0f, 0.0f, 0.0f,
481 0.0f, 0.0f, 1.0f, 0.0f,
482 0.0f, 0.0f, -1.0f, 1.0f
485 struct sVertex far_quad1[] =
487 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
488 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
489 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
490 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
492 struct sVertex far_quad2[] =
494 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
495 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
496 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
497 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
500 memset(&caps, 0, sizeof(caps));
501 hr = IDirect3DDevice7_GetCaps(device, &caps);
502 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
503 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
504 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr);
506 /* Setup initial states: No lighting, fog on, fog color */
507 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
508 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
509 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE);
510 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
511 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */);
512 ok(hr == D3D_OK, "Setting fog color returned %08x\n", hr);
514 /* First test: Both table fog and vertex fog off */
515 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
516 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
517 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
518 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
520 /* Start = 0, end = 1. Should be default, but set them */
521 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start));
522 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
523 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end));
524 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
526 if(IDirect3DDevice7_BeginScene(device) == D3D_OK)
528 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
529 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
530 untransformed_1, 4, Indices, 6, 0);
531 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
533 /* That makes it use the Z value */
534 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
535 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
536 /* Untransformed, vertex fog != none (or table fog != none):
537 * Use the Z value as input into the equation
539 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
540 untransformed_2, 4, Indices, 6, 0);
541 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
543 /* transformed verts */
544 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
545 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
546 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
547 transformed_1, 4, Indices, 6, 0);
548 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
550 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
551 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
552 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
555 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
556 transformed_2, 4, Indices, 6, 0);
557 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
559 hr = IDirect3DDevice7_EndScene(device);
560 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
564 ok(FALSE, "BeginScene failed\n");
567 color = getPixelColor(device, 160, 360);
568 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
569 color = getPixelColor(device, 160, 120);
570 ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
571 color = getPixelColor(device, 480, 120);
572 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
573 if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
575 color = getPixelColor(device, 480, 360);
576 ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
580 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
581 * The settings above result in no fogging with vertex fog
583 color = getPixelColor(device, 480, 120);
584 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
585 trace("Info: Table fog not supported by this device\n");
588 if (caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
590 /* A simple fog + non-identity world matrix test */
591 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat1);
592 ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %#08x\n", hr);
594 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
595 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
596 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
597 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
599 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
600 ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %#08x\n", hr);
602 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
604 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
605 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad1, 4, Indices, 6, 0);
606 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
608 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
609 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad2, 4, Indices, 6, 0);
610 ok(hr == D3D_OK, "DrawIndexedPrimitive returned %#08x\n", hr);
612 hr = IDirect3DDevice7_EndScene(device);
613 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
617 ok(FALSE, "BeginScene failed\n");
620 color = getPixelColor(device, 160, 360);
621 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
622 color = getPixelColor(device, 160, 120);
623 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
625 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
626 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)world_mat2);
627 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
628 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)proj_mat);
629 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
631 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
632 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
634 if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
636 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
637 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_1, 4, Indices, 6, 0);
638 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
640 hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
641 D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, untransformed_2, 4, Indices, 6, 0);
642 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
644 hr = IDirect3DDevice7_EndScene(device);
645 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
649 ok(FALSE, "BeginScene failed\n");
652 color = getPixelColor(device, 160, 360);
653 todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
654 color = getPixelColor(device, 160, 120);
655 ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
657 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *)ident_mat);
658 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
659 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *)ident_mat);
660 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
664 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
667 /* Turn off the fog master switch to avoid confusing other tests */
668 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
669 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
672 static void blt_test(IDirect3DDevice7 *device)
674 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
678 memset(&ddsd, 0, sizeof(ddsd));
679 ddsd.dwSize = sizeof(ddsd);
680 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
681 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
684 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
685 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
686 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
688 /* Offscreen blits with the same source as destination */
691 RECT src_rect, dst_rect;
693 /* Blit the whole surface to itself */
694 hr = IDirectDrawSurface_Blt(offscreen, NULL, offscreen, NULL, 0, NULL);
695 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
697 /* Overlapped blit */
698 dst_rect.left = 0; dst_rect.right = 480;
699 dst_rect.top = 0; dst_rect.bottom = 480;
700 src_rect.left = 160; src_rect.right = 640;
701 src_rect.top = 0; src_rect.bottom = 480;
702 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
703 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
705 /* Overlapped blit, flip-y through source rectangle (not allowed) */
706 dst_rect.left = 0; dst_rect.right = 480;
707 dst_rect.top = 0; dst_rect.bottom = 480;
708 src_rect.left = 160; src_rect.right = 640;
709 src_rect.top = 480; src_rect.bottom = 0;
710 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
711 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface7_Blt returned %08x\n", hr);
713 /* Overlapped blit, with shrinking in x */
714 dst_rect.left = 0; dst_rect.right = 480;
715 dst_rect.top = 0; dst_rect.bottom = 480;
716 src_rect.left = 160; src_rect.right = 480;
717 src_rect.top = 0; src_rect.bottom = 480;
718 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
719 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
722 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
723 ok(hr == D3D_OK, "Unable to obtain a surface pointer to the backbuffer, hr = %08x\n", hr);
725 /* backbuffer ==> texture blits */
726 if(SUCCEEDED(hr) && offscreen)
728 RECT src_rect, dst_rect;
730 /* backbuffer ==> texture, src_rect=NULL, dst_rect=NULL, no scaling */
731 hr = IDirectDrawSurface_Blt(offscreen, NULL, backbuffer, NULL, 0, NULL);
732 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
734 /* backbuffer ==> texture, full surface blits, no scaling */
735 dst_rect.left = 0; dst_rect.right = 640;
736 dst_rect.top = 0; dst_rect.bottom = 480;
737 src_rect.left = 0; src_rect.right = 640;
738 src_rect.top = 0; src_rect.bottom = 480;
739 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
740 ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
742 /* backbuffer ==> texture, flip in y-direction through source rectangle, no scaling (allowed) */
743 dst_rect.left = 0; dst_rect.right = 640;
744 dst_rect.top = 480; dst_rect.top = 0;
745 src_rect.left = 0; src_rect.right = 640;
746 src_rect.top = 0; src_rect.bottom = 480;
747 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
748 ok(hr == DD_OK, "backbuffer => texture flip-y src_rect failed with hr = %08x\n", hr);
750 /* backbuffer ==> texture, flip in x-direction through source rectangle, no scaling (not allowed) */
751 dst_rect.left = 640; dst_rect.right = 0;
752 dst_rect.top = 0; dst_rect.top = 480;
753 src_rect.left = 0; src_rect.right = 640;
754 src_rect.top = 0; src_rect.bottom = 480;
755 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
756 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x src_rect failed with hr = %08x\n", hr);
758 /* backbuffer ==> texture, flip in y-direction through destination rectangle (not allowed) */
759 dst_rect.left = 0; dst_rect.right = 640;
760 dst_rect.top = 0; dst_rect.top = 480;
761 src_rect.left = 0; src_rect.right = 640;
762 src_rect.top = 480; src_rect.bottom = 0;
763 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
764 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-y dst_rect failed with hr = %08x\n", hr);
766 /* backbuffer ==> texture, flip in x-direction through destination rectangle, no scaling (not allowed) */
767 dst_rect.left = 0; dst_rect.right = 640;
768 dst_rect.top = 0; dst_rect.top = 480;
769 src_rect.left = 640; src_rect.right = 0;
770 src_rect.top = 0; src_rect.bottom = 480;
771 hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
772 ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x dst_rect failed with hr = %08x\n", hr);
775 if(offscreen) IDirectDrawSurface7_Release(offscreen);
776 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
779 static void offscreen_test(IDirect3DDevice7 *device)
782 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
786 static float quad[][5] = {
787 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
788 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
789 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
790 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
793 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
794 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
796 memset(&ddsd, 0, sizeof(ddsd));
797 ddsd.dwSize = sizeof(ddsd);
798 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
799 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
802 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
803 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
804 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
809 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
810 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
815 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
816 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
817 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
818 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
819 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
820 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
821 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
822 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
823 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
824 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
827 win_skip("Tests would crash on W2K with a refdevice\n");
831 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
832 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
833 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
834 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
835 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
837 /* Draw without textures - Should result in a white quad */
838 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
839 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
841 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
842 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
843 set_the_same_viewport_again(device);
845 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
846 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
848 /* This time with the texture */
849 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
850 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
852 IDirect3DDevice7_EndScene(device);
855 /* Center quad - should be white */
856 color = getPixelColor(device, 320, 240);
857 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
858 /* Some quad in the cleared part of the texture */
859 color = getPixelColor(device, 170, 240);
860 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
861 /* Part of the originally cleared back buffer */
862 color = getPixelColor(device, 10, 10);
863 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
865 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
866 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
867 * the offscreen rendering mode this test would succeed or fail
869 color = getPixelColor(device, 10, 470);
870 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
874 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
875 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetTexture returned %#x.\n", hr);
879 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
880 ok(SUCCEEDED(hr), "IDirect3DDevice7_SetRenderTarget returned %#x.\n", hr);
881 IDirectDrawSurface7_Release(backbuffer);
884 IDirectDrawSurface7_Release(offscreen);
888 static void alpha_test(IDirect3DDevice7 *device)
891 IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
892 DWORD color, red, green, blue;
895 struct vertex quad1[] =
897 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
898 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
899 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
900 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
902 struct vertex quad2[] =
904 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
905 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
906 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
907 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
909 static float composite_quad[][5] = {
910 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
911 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
912 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
913 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
916 /* Clear the render target with alpha = 0.5 */
917 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
918 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
920 memset(&ddsd, 0, sizeof(ddsd));
921 ddsd.dwSize = sizeof(ddsd);
922 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
925 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
926 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
927 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
928 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
929 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
930 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000ff;
931 U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
932 hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
933 ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
937 hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
938 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
943 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
944 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
945 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
946 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
947 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
948 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
949 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
950 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
952 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
953 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
956 win_skip("Tests would crash on W2K with a refdevice\n");
960 if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
962 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
963 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
966 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
967 * They give essentially ZERO and ONE blend factors
969 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
970 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
971 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
972 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
973 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
974 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
976 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
977 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
978 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
979 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
980 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
981 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
983 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
984 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
985 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
986 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
989 hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
990 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
991 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
992 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
994 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
995 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
996 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
997 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
998 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
999 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1001 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
1002 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1003 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
1004 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1005 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
1006 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1008 hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
1009 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1010 set_the_same_viewport_again(device);
1012 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1013 * Disable alpha blending for the final composition
1015 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
1016 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
1018 hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
1019 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1020 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
1021 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1022 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
1023 ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
1025 hr = IDirect3DDevice7_EndScene(device);
1026 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1029 color = getPixelColor(device, 160, 360);
1030 red = (color & 0x00ff0000) >> 16;
1031 green = (color & 0x0000ff00) >> 8;
1032 blue = (color & 0x000000ff);
1033 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1034 "SRCALPHA on frame buffer returned color 0x%08x, expected 0x00bf4000\n", color);
1036 color = getPixelColor(device, 160, 120);
1037 red = (color & 0x00ff0000) >> 16;
1038 green = (color & 0x0000ff00) >> 8;
1039 blue = (color & 0x000000ff);
1040 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
1041 "DSTALPHA on frame buffer returned color 0x%08x, expected 0x000000ff\n", color);
1043 color = getPixelColor(device, 480, 360);
1044 red = (color & 0x00ff0000) >> 16;
1045 green = (color & 0x0000ff00) >> 8;
1046 blue = (color & 0x000000ff);
1047 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
1048 "SRCALPHA on texture returned color 0x%08x, expected 0x00bf4000\n", color);
1050 color = getPixelColor(device, 480, 120);
1051 red = (color & 0x00ff0000) >> 16;
1052 green = (color & 0x0000ff00) >> 8;
1053 blue = (color & 0x000000ff);
1054 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
1055 "DSTALPHA on texture returned color 0x%08x, expected 0x00800080\n", color);
1058 if(offscreen) IDirectDrawSurface7_Release(offscreen);
1059 if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
1062 static void rhw_zero_test(IDirect3DDevice7 *device)
1064 /* Test if it will render a quad correctly when vertex rhw = 0 */
1074 {0, 100, 0, 0, 0xffffffff},
1075 {0, 0, 0, 0, 0xffffffff},
1076 {100, 100, 0, 0, 0xffffffff},
1077 {100, 0, 0, 0, 0xffffffff},
1080 /* Clear to black */
1081 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
1082 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1084 hr = IDirect3DDevice7_BeginScene(device);
1085 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
1087 if (SUCCEEDED(hr)) {
1088 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
1089 ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
1091 hr = IDirect3DDevice7_EndScene(device);
1092 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1095 color = getPixelColor(device, 5, 5);
1096 ok(color == 0xffffff ||
1097 broken(color == 0), /* VMware */
1098 "Got color %08x, expected 00ffffff\n", color);
1100 color = getPixelColor(device, 105, 105);
1101 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1104 static BOOL D3D1_createObjects(void)
1109 D3DEXECUTEBUFFERDESC exdesc;
1110 D3DVIEWPORT vp_data;
1112 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1113 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1115 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1120 wc.lpfnWndProc = DefWindowProc;
1121 wc.lpszClassName = "texturemapblend_test_wc";
1123 window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1125 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1126 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1131 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
1133 /* 24 bit is fine too */
1134 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
1136 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1141 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1142 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1147 memset(&ddsd, 0, sizeof(ddsd));
1148 ddsd.dwSize = sizeof(ddsd);
1149 ddsd.dwFlags = DDSD_CAPS;
1150 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
1151 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1152 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1157 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
1159 trace("Creating a HAL device failed, trying Ref\n");
1160 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
1162 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
1167 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1168 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1173 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1174 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1175 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1176 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1177 vp_data.dwSize = sizeof(vp_data);
1180 vp_data.dwWidth = 640;
1181 vp_data.dwHeight = 480;
1182 vp_data.dvScaleX = 1;
1183 vp_data.dvScaleY = 1;
1184 vp_data.dvMaxX = 640;
1185 vp_data.dvMaxY = 480;
1188 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1189 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1191 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1192 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1193 exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1194 exdesc.dwBufferSize = 512;
1195 exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
1196 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
1197 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
1205 static void D3D1_releaseObjects(void)
1207 if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1208 if(Surface1) IDirectDrawSurface_Release(Surface1);
1209 if(Viewport) IDirect3DViewport_Release(Viewport);
1210 if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1211 if(Direct3D1) IDirect3D_Release(Direct3D1);
1212 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1213 if(window) DestroyWindow(window);
1216 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
1221 RECT rectToLock = {x, y, x+1, y+1};
1222 IDirectDrawSurface *surf = NULL;
1224 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
1225 * to an offscreen surface and lock it instead of the front buffer
1227 memset(&ddsd, 0, sizeof(ddsd));
1228 ddsd.dwSize = sizeof(ddsd);
1229 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1230 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
1232 ddsd.dwHeight = 480;
1233 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
1234 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
1235 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
1238 trace("cannot create helper surface\n");
1242 memset(&ddsd, 0, sizeof(ddsd));
1243 ddsd.dwSize = sizeof(ddsd);
1244 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1246 hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
1247 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
1250 trace("Cannot blit\n");
1255 hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
1258 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
1263 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
1264 * really important for these tests
1266 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
1267 hr = IDirectDrawSurface_Unlock(surf, NULL);
1270 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
1274 IDirectDrawSurface_Release(surf);
1278 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
1279 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
1280 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
1281 ((D3DINSTRUCTION*)(ptr))->wCount = count;\
1282 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1284 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
1285 U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
1286 U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
1287 ptr = ((D3DSTATE*)(ptr))+1; } while (0)
1289 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
1290 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
1291 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
1292 ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1293 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1294 ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1295 ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1296 ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1297 ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1298 ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1299 ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1301 #define EXEBUF_END(ptr) do {\
1302 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1303 ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1304 ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1305 ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1307 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1308 ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1309 ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1310 ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1311 ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1312 U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1313 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1314 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1315 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1316 ptr = ((D3DTRIANGLE*)ptr)+1;\
1317 U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1318 U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1319 U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1320 ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1321 ptr = ((D3DTRIANGLE*)(ptr))+1;\
1324 static HRESULT CALLBACK TextureFormatEnumCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext)
1326 if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1327 *(BOOL*)lpContext = TRUE;
1330 return DDENUMRET_OK;
1333 static void D3D1_TextureMapBlendTest(void)
1337 D3DEXECUTEBUFFERDESC exdesc;
1338 D3DEXECUTEDATA exdata;
1340 RECT rect = { 0, 0, 64, 128 };
1341 DWORD color, red, blue, green;
1342 void *exe_buffer_ptr;
1344 D3DTEXTUREHANDLE htex;
1346 IDirectDrawSurface *TexSurface = NULL;
1347 IDirect3DTexture *Texture = NULL;
1348 IDirectDrawPalette *Palette = NULL;
1349 PALETTEENTRY table1[256];
1350 BOOL p8_textures_supported = FALSE;
1360 {0.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1361 {640.0f, 0.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1362 {640.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1363 {0.0f, 240.0f, 0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1364 {0.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1365 {640.0f, 240.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1366 {640.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1367 {0.0f, 480.0f, 0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1370 {0.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1371 {640.0f, 0.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1372 {640.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1373 {0.0f, 240.0f, 0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1374 {0.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1375 {640.0f, 240.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1376 {640.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1377 {0.0f, 480.0f, 0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1380 /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1381 memset (&ddsd, 0, sizeof (ddsd));
1382 ddsd.dwSize = sizeof (ddsd);
1383 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1384 ddsd.dwHeight = 128;
1386 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1387 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1388 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1389 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1390 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1391 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1392 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1393 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1394 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1395 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1397 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1401 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1403 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1405 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1409 memset(&ddbltfx, 0, sizeof(ddbltfx));
1410 ddbltfx.dwSize = sizeof(ddbltfx);
1411 U5(ddbltfx).dwFillColor = 0;
1412 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1413 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1415 U5(ddbltfx).dwFillColor = 0xff0000ff;
1416 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1417 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1418 U5(ddbltfx).dwFillColor = 0x800000ff;
1419 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1420 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1422 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1423 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1424 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1425 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1427 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1431 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1433 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1435 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1437 EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1438 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, exe_buffer_ptr);
1439 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE, FALSE, exe_buffer_ptr);
1440 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE, FALSE, exe_buffer_ptr);
1441 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE, FALSE, exe_buffer_ptr);
1442 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_NEAREST, exe_buffer_ptr);
1443 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_NEAREST, exe_buffer_ptr);
1444 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE , D3DFILL_SOLID, exe_buffer_ptr);
1445 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA, exe_buffer_ptr);
1446 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA, exe_buffer_ptr);
1447 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1448 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, exe_buffer_ptr);
1449 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1450 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1451 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1453 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1454 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1456 EXEBUF_END(exe_buffer_ptr);
1458 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1460 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1462 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1465 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1466 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1467 exdata.dwVertexCount = 8;
1468 exdata.dwInstructionOffset = 256;
1469 exdata.dwInstructionLength = exe_length;
1470 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1471 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1473 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1474 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1476 if (SUCCEEDED(hr)) {
1477 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1478 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1479 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1480 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1483 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1484 red = (color & 0x00ff0000) >> 16;
1485 green = (color & 0x0000ff00) >> 8;
1486 blue = (color & 0x000000ff);
1487 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1489 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1490 red = (color & 0x00ff0000) >> 16;
1491 green = (color & 0x0000ff00) >> 8;
1492 blue = (color & 0x000000ff);
1493 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1495 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1496 red = (color & 0x00ff0000) >> 16;
1497 green = (color & 0x0000ff00) >> 8;
1498 blue = (color & 0x000000ff);
1499 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1501 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1502 red = (color & 0x00ff0000) >> 16;
1503 green = (color & 0x0000ff00) >> 8;
1504 blue = (color & 0x000000ff);
1505 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1507 /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1508 if(Texture) IDirect3DTexture_Release(Texture);
1510 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1513 memset (&ddsd, 0, sizeof (ddsd));
1514 ddsd.dwSize = sizeof (ddsd);
1515 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1516 ddsd.dwHeight = 128;
1518 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1519 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1520 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1521 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1522 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1523 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1524 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1526 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1527 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1529 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1533 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1535 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1537 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1541 memset(&ddbltfx, 0, sizeof(ddbltfx));
1542 ddbltfx.dwSize = sizeof(ddbltfx);
1543 U5(ddbltfx).dwFillColor = 0;
1544 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1545 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1547 U5(ddbltfx).dwFillColor = 0xff0000ff;
1548 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1549 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1550 U5(ddbltfx).dwFillColor = 0x800000ff;
1551 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1552 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1554 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1555 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1556 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1557 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1559 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1563 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1565 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1567 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1569 EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1570 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1571 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1572 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1574 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1575 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1577 EXEBUF_END(exe_buffer_ptr);
1579 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1581 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1583 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1586 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1587 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1588 exdata.dwVertexCount = 8;
1589 exdata.dwInstructionOffset = 256;
1590 exdata.dwInstructionLength = exe_length;
1591 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1592 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1594 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1595 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1597 if (SUCCEEDED(hr)) {
1598 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1599 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1600 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1601 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1604 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1605 red = (color & 0x00ff0000) >> 16;
1606 green = (color & 0x0000ff00) >> 8;
1607 blue = (color & 0x000000ff);
1608 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1610 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1611 red = (color & 0x00ff0000) >> 16;
1612 green = (color & 0x0000ff00) >> 8;
1613 blue = (color & 0x000000ff);
1614 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1616 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1617 red = (color & 0x00ff0000) >> 16;
1618 green = (color & 0x0000ff00) >> 8;
1619 blue = (color & 0x000000ff);
1620 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1622 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1623 red = (color & 0x00ff0000) >> 16;
1624 green = (color & 0x0000ff00) >> 8;
1625 blue = (color & 0x000000ff);
1626 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1628 /* 3) Test RGB - should multiply color components from diffuse color and texture */
1629 if(Texture) IDirect3DTexture_Release(Texture);
1631 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1634 memset (&ddsd, 0, sizeof (ddsd));
1635 ddsd.dwSize = sizeof (ddsd);
1636 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1637 ddsd.dwHeight = 128;
1639 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1640 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1641 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1642 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1643 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1644 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1645 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
1646 U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1647 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1648 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1650 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1654 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1656 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1658 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1662 memset(&ddbltfx, 0, sizeof(ddbltfx));
1663 ddbltfx.dwSize = sizeof(ddbltfx);
1664 U5(ddbltfx).dwFillColor = 0;
1665 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1666 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1668 U5(ddbltfx).dwFillColor = 0x00ffffff;
1669 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1670 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1671 U5(ddbltfx).dwFillColor = 0x00ffff80;
1672 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1673 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1675 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1676 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1677 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1678 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1680 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1684 memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1686 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1688 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1690 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1691 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1692 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1693 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1694 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1696 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1697 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1699 EXEBUF_END(exe_buffer_ptr);
1701 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1703 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1705 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1708 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1709 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1710 exdata.dwVertexCount = 8;
1711 exdata.dwInstructionOffset = 256;
1712 exdata.dwInstructionLength = exe_length;
1713 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1714 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1716 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1717 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1719 if (SUCCEEDED(hr)) {
1720 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1721 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1722 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1723 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1726 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1727 red = (color & 0x00ff0000) >> 16;
1728 green = (color & 0x0000ff00) >> 8;
1729 blue = (color & 0x000000ff);
1730 ok(red == 0xff && green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1732 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1733 red = (color & 0x00ff0000) >> 16;
1734 green = (color & 0x0000ff00) >> 8;
1735 blue = (color & 0x000000ff);
1736 ok(red == 0xff && green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1738 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1739 red = (color & 0x00ff0000) >> 16;
1740 green = (color & 0x0000ff00) >> 8;
1741 blue = (color & 0x000000ff);
1742 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1744 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1745 red = (color & 0x00ff0000) >> 16;
1746 green = (color & 0x0000ff00) >> 8;
1747 blue = (color & 0x000000ff);
1748 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1750 /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1751 if(Texture) IDirect3DTexture_Release(Texture);
1753 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1756 memset (&ddsd, 0, sizeof (ddsd));
1757 ddsd.dwSize = sizeof (ddsd);
1758 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1759 ddsd.dwHeight = 128;
1761 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1762 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1763 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1764 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
1765 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xf800;
1766 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07e0;
1767 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001f;
1769 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1770 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1772 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1776 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1778 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1780 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1784 memset(&ddbltfx, 0, sizeof(ddbltfx));
1785 ddbltfx.dwSize = sizeof(ddbltfx);
1786 U5(ddbltfx).dwFillColor = 0;
1787 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1788 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1789 U5(ddbltfx).dwFillColor = 0xf800;
1790 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1791 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1792 U5(ddbltfx).dwFillColor = 0x001f;
1793 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1794 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1796 clrKey.dwColorSpaceLowValue = 0x001f;
1797 clrKey.dwColorSpaceHighValue = 0x001f;
1798 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1799 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1801 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1802 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1803 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1804 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1806 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1810 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1812 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1814 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1816 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1817 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1818 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1819 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1820 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1822 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1823 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1825 EXEBUF_END(exe_buffer_ptr);
1827 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1829 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1831 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1834 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1835 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1836 exdata.dwVertexCount = 8;
1837 exdata.dwInstructionOffset = 256;
1838 exdata.dwInstructionLength = exe_length;
1839 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1840 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1842 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1843 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1845 if (SUCCEEDED(hr)) {
1846 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1847 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1848 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1849 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1852 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1853 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1855 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1856 red = (color & 0x00ff0000) >> 16;
1857 green = (color & 0x0000ff00) >> 8;
1858 blue = (color & 0x000000ff);
1859 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1861 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1862 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1864 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1865 red = (color & 0x00ff0000) >> 16;
1866 green = (color & 0x0000ff00) >> 8;
1867 blue = (color & 0x000000ff);
1868 ok(red >= 0x7e && red <= 0x82 && green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1870 /* 5) Test alpha again, now with color keyed P8 texture */
1871 if(Texture) IDirect3DTexture_Release(Texture);
1873 if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1876 hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1877 &p8_textures_supported);
1878 ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1880 if (!p8_textures_supported) {
1881 skip("device has no P8 texture support, skipping test\n");
1883 memset (&ddsd, 0, sizeof (ddsd));
1884 ddsd.dwSize = sizeof (ddsd);
1885 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1886 ddsd.dwHeight = 128;
1888 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1889 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1890 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1891 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1893 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1894 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1896 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1900 memset(table1, 0, sizeof(table1));
1901 table1[0].peBlue = 0xff;
1902 table1[1].peRed = 0xff;
1904 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1905 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1907 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1911 hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1912 ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1914 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1916 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1918 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1922 memset(&ddbltfx, 0, sizeof(ddbltfx));
1923 ddbltfx.dwSize = sizeof(ddbltfx);
1924 U5(ddbltfx).dwFillColor = 0;
1925 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1926 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1927 U5(ddbltfx).dwFillColor = 0;
1928 hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1929 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1930 U5(ddbltfx).dwFillColor = 1;
1931 hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1932 ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1934 clrKey.dwColorSpaceLowValue = 1;
1935 clrKey.dwColorSpaceHighValue = 1;
1936 hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1937 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1939 memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1940 exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1941 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1942 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1944 skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1948 memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1950 exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1952 EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1954 EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1955 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1956 hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1957 ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1958 EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE, htex, exe_buffer_ptr);
1960 EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1961 EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1963 EXEBUF_END(exe_buffer_ptr);
1965 exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1967 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1969 trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1972 memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1973 exdata.dwSize = sizeof(D3DEXECUTEDATA);
1974 exdata.dwVertexCount = 8;
1975 exdata.dwInstructionOffset = 256;
1976 exdata.dwInstructionLength = exe_length;
1977 hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1978 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1980 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1981 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1983 if (SUCCEEDED(hr)) {
1984 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1985 ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1986 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1987 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1990 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1991 ok(color == 0, "Got color %08x, expected 00000000\n", color);
1993 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1994 red = (color & 0x00ff0000) >> 16;
1995 green = (color & 0x0000ff00) >> 8;
1996 blue = (color & 0x000000ff);
1997 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1999 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
2000 ok(color == 0, "Got color %08x, expected 00000000\n", color);
2002 color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
2003 red = (color & 0x00ff0000) >> 16;
2004 green = (color & 0x0000ff00) >> 8;
2005 blue = (color & 0x000000ff);
2006 ok(red == 0 && green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
2011 if (Palette) IDirectDrawPalette_Release(Palette);
2012 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
2013 if (Texture) IDirect3DTexture_Release(Texture);
2016 static void D3D1_ViewportClearTest(void)
2019 IDirect3DMaterial *bgMaterial = NULL;
2021 D3DMATERIALHANDLE hMat;
2022 D3DVIEWPORT vp_data;
2023 IDirect3DViewport *Viewport2 = NULL;
2024 DWORD color, red, green, blue;
2026 hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
2027 ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
2032 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
2033 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
2038 hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
2039 ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
2040 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
2041 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
2042 vp_data.dwSize = sizeof(vp_data);
2045 vp_data.dwWidth = 100;
2046 vp_data.dwHeight = 100;
2047 vp_data.dvScaleX = 1;
2048 vp_data.dvScaleY = 1;
2049 vp_data.dvMaxX = 100;
2050 vp_data.dvMaxY = 100;
2053 hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
2054 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
2056 memset(&mat, 0, sizeof(mat));
2057 mat.dwSize = sizeof(mat);
2058 U1(U(mat).diffuse).r = 1.0f;
2059 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2060 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2062 hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
2063 ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
2065 hr = IDirect3DViewport_SetBackground(Viewport, hMat);
2066 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2067 hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
2068 ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
2070 hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
2071 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2073 if (SUCCEEDED(hr)) {
2076 U1(rect).x1 = U2(rect).y1 = 0;
2080 hr = IDirect3DViewport_Clear(Viewport, 1, &rect, D3DCLEAR_TARGET);
2081 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2083 memset(&mat, 0, sizeof(mat));
2084 mat.dwSize = sizeof(mat);
2085 U3(U(mat).diffuse).b = 1.0f;
2086 hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
2087 ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
2089 hr = IDirect3DViewport_Clear(Viewport2, 1, &rect, D3DCLEAR_TARGET);
2090 ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
2092 hr = IDirect3DDevice_EndScene(Direct3DDevice1);
2093 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2096 color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
2097 red = (color & 0x00ff0000) >> 16;
2098 green = (color & 0x0000ff00) >> 8;
2099 blue = (color & 0x000000ff);
2100 ok((red == 0xff && green == 0 && blue == 0) ||
2101 broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
2102 "Got color %08x, expected 00ff0000\n", color);
2104 color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
2105 red = (color & 0x00ff0000) >> 16;
2106 green = (color & 0x0000ff00) >> 8;
2107 blue = (color & 0x000000ff);
2108 ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
2112 if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
2113 if (Viewport2) IDirect3DViewport_Release(Viewport2);
2116 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
2120 DDSURFACEDESC2 ddsd;
2121 RECT rectToLock = {x, y, x+1, y+1};
2122 IDirectDrawSurface4 *surf = NULL;
2124 /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
2125 * to an offscreen surface and lock it instead of the front buffer
2127 memset(&ddsd, 0, sizeof(ddsd));
2128 ddsd.dwSize = sizeof(ddsd);
2129 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2130 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
2132 ddsd.dwHeight = 480;
2133 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
2134 hr = IDirectDraw4_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
2135 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2138 trace("cannot create helper surface\n");
2142 memset(&ddsd, 0, sizeof(ddsd));
2143 ddsd.dwSize = sizeof(ddsd);
2144 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2146 hr = IDirectDrawSurface4_BltFast(surf, 0, 0, Surface, NULL, 0);
2147 ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
2150 trace("Cannot blit\n");
2155 hr = IDirectDrawSurface4_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
2158 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
2163 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
2164 * really important for these tests
2166 ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
2167 hr = IDirectDrawSurface4_Unlock(surf, NULL);
2170 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
2174 IDirectDrawSurface4_Release(surf);
2178 static void D3D3_ViewportClearTest(void)
2181 IDirectDraw *DirectDraw1 = NULL;
2182 IDirectDraw4 *DirectDraw4 = NULL;
2183 IDirectDrawSurface4 *Primary = NULL;
2184 IDirect3D3 *Direct3D3 = NULL;
2185 IDirect3DViewport3 *Viewport3 = NULL;
2186 IDirect3DViewport3 *SmallViewport3 = NULL;
2187 IDirect3DDevice3 *Direct3DDevice3 = NULL;
2189 DDSURFACEDESC2 ddsd;
2190 D3DVIEWPORT2 vp_data;
2191 DWORD color, red, green, blue;
2193 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
2194 0.0f, 1.0f, 0.0f, 0.0f,
2195 0.0f, 0.0f, 1.0f, 0.0f,
2196 0.0f, 0.0f, 0.0f, 1.0f };
2197 struct vertex quad[] =
2199 {-1.0f, -1.0f, 0.1f, 0xffffffff},
2200 {-1.0f, 1.0f, 0.1f, 0xffffffff},
2201 { 1.0f, 1.0f, 0.1f, 0xffffffff},
2202 { 1.0f, -1.0f, 0.1f, 0xffffffff},
2205 WORD Indices[] = {0, 1, 2, 2, 3, 0};
2206 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
2208 wc.lpfnWndProc = DefWindowProc;
2209 wc.lpszClassName = "D3D3_ViewportClearTest_wc";
2211 window = CreateWindow("D3D3_ViewportClearTest_wc", "D3D3_ViewportClearTest",
2212 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2214 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2215 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2216 if(FAILED(hr)) goto out;
2218 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2219 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2220 if(FAILED(hr)) goto out;
2222 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2224 /* 24 bit is fine too */
2225 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2227 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2228 if (FAILED(hr)) goto out;
2230 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void**)&DirectDraw4);
2231 ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
2232 if(FAILED(hr)) goto out;
2234 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2235 ddsd.dwSize = sizeof(DDSURFACEDESC2);
2236 ddsd.dwFlags = DDSD_CAPS;
2237 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
2239 hr = IDirectDraw_CreateSurface(DirectDraw4, &ddsd, &Primary, NULL);
2240 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2241 if(FAILED(hr)) goto out;
2243 hr = IDirectDraw4_QueryInterface(DirectDraw4, &IID_IDirect3D3, (void**)&Direct3D3);
2244 ok(hr==DD_OK, "IDirectDraw4_QueryInterface returned: %08x\n", hr);
2245 if(FAILED(hr)) goto out;
2247 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DHALDevice, Primary, &Direct3DDevice3, NULL);
2249 trace("Creating a HAL device failed, trying Ref\n");
2250 hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DRefDevice, Primary, &Direct3DDevice3, NULL);
2252 ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
2253 if(FAILED(hr)) goto out;
2255 hr = IDirect3D3_CreateViewport(Direct3D3, &Viewport3, NULL);
2256 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2257 if(FAILED(hr)) goto out;
2259 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, Viewport3);
2260 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2262 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2263 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2264 vp_data.dwWidth = 640;
2265 vp_data.dwHeight = 480;
2266 vp_data.dvClipX = -1.0f;
2267 vp_data.dvClipWidth = 2.0f;
2268 vp_data.dvClipY = 1.0f;
2269 vp_data.dvClipHeight = 2.0f;
2270 vp_data.dvMaxZ = 1.0f;
2271 hr = IDirect3DViewport3_SetViewport2(Viewport3, &vp_data);
2272 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2274 hr = IDirect3D3_CreateViewport(Direct3D3, &SmallViewport3, NULL);
2275 ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2276 if(FAILED(hr)) goto out;
2278 hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, SmallViewport3);
2279 ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2281 memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2282 vp_data.dwSize = sizeof(D3DVIEWPORT2);
2285 vp_data.dwWidth = 100;
2286 vp_data.dwHeight = 100;
2287 vp_data.dvClipX = -1.0f;
2288 vp_data.dvClipWidth = 2.0f;
2289 vp_data.dvClipY = 1.0f;
2290 vp_data.dvClipHeight = 2.0f;
2291 vp_data.dvMaxZ = 1.0f;
2292 hr = IDirect3DViewport3_SetViewport2(SmallViewport3, &vp_data);
2293 ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2295 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2296 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2298 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
2299 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2300 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
2301 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2302 hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
2303 ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2304 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CLIPPING, FALSE);
2305 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2306 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ZENABLE, FALSE);
2307 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2308 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_FOGENABLE, FALSE);
2309 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2310 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_STENCILENABLE, FALSE);
2311 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2312 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
2313 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2314 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
2315 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2316 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
2317 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState failed with %08x\n", hr);
2318 hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
2319 ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2321 if (SUCCEEDED(hr)) {
2322 U1(rect).x1 = U2(rect).y1 = 0;
2326 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x00ff00, 0.0f, 0);
2327 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2329 hr = IDirect3DViewport3_Clear2(SmallViewport3, 1, &rect, D3DCLEAR_TARGET, 0xff0000, 0.0f, 0);
2330 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2332 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2333 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2336 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2337 red = (color & 0x00ff0000) >> 16;
2338 green = (color & 0x0000ff00) >> 8;
2339 blue = (color & 0x000000ff);
2340 ok(red == 0 && green == 0xff && blue == 0, "Got color %08x, expected 0000ff00\n", color);
2342 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2343 red = (color & 0x00ff0000) >> 16;
2344 green = (color & 0x0000ff00) >> 8;
2345 blue = (color & 0x000000ff);
2346 ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000\n", color);
2348 /* Test that clearing viewport doesn't interfere with rendering to previously active viewport. */
2349 hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2350 ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2352 if (SUCCEEDED(hr)) {
2353 hr = IDirect3DDevice3_SetCurrentViewport(Direct3DDevice3, SmallViewport3);
2354 ok(hr == D3D_OK, "IDirect3DDevice3_SetCurrentViewport failed with %08x\n", hr);
2356 hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x000000, 0.0f, 0);
2357 ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2359 hr = IDirect3DDevice3_DrawIndexedPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf, quad, 4 /* NumVerts */,
2360 Indices, 6 /* Indexcount */, 0 /* flags */);
2361 ok(hr == D3D_OK, "IDirect3DDevice3_DrawIndexedPrimitive failed with %08x\n", hr);
2363 hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2364 ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2367 color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2368 red = (color & 0x00ff0000) >> 16;
2369 green = (color & 0x0000ff00) >> 8;
2370 blue = (color & 0x000000ff);
2371 ok(red == 0 && green == 0 && blue == 0, "Got color %08x, expected 00000000\n", color);
2373 color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2374 red = (color & 0x00ff0000) >> 16;
2375 green = (color & 0x0000ff00) >> 8;
2376 blue = (color & 0x000000ff);
2377 ok(red == 0xff && green == 0xff && blue == 0xff, "Got color %08x, expected 00ffffff\n", color);
2381 if (SmallViewport3) IDirect3DViewport3_Release(SmallViewport3);
2382 if (Viewport3) IDirect3DViewport3_Release(Viewport3);
2383 if (Direct3DDevice3) IDirect3DDevice3_Release(Direct3DDevice3);
2384 if (Direct3D3) IDirect3D3_Release(Direct3D3);
2385 if (Primary) IDirectDrawSurface4_Release(Primary);
2386 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
2387 if (DirectDraw4) IDirectDraw4_Release(DirectDraw4);
2388 if(window) DestroyWindow(window);
2391 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
2398 memset(&ddsd, 0, sizeof(ddsd));
2399 ddsd.dwSize = sizeof(ddsd);
2401 hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
2402 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2404 p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2406 for (i = 0; i < h; i++) {
2407 for (i1 = 0; i1 < w; i1++) {
2410 p += U1(ddsd).lPitch;
2413 hr = IDirectDrawSurface_Unlock(dest, NULL);
2414 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2417 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
2419 COLORREF clr = CLR_INVALID;
2423 hr = IDirectDrawSurface_GetDC(Surface, &hdc);
2424 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2426 if (SUCCEEDED(hr)) {
2427 clr = GetPixel(hdc, x, y);
2429 hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
2430 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2436 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
2440 for (i = 0; i < 256; i++) {
2441 if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
2442 table1[i].peBlue != table2[i].rgbBlue) return FALSE;
2448 static void p8_primary_test(void)
2450 /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
2454 PALETTEENTRY entries[256];
2455 RGBQUAD coltable[256];
2457 IDirectDrawPalette *ddprimpal = NULL;
2458 IDirectDrawSurface *offscreen = NULL;
2464 unsigned differences;
2466 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
2467 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
2469 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2474 wc.lpfnWndProc = DefWindowProc;
2475 wc.lpszClassName = "p8_primary_test_wc";
2477 window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2479 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2480 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2485 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
2486 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2491 memset(&ddsd, 0, sizeof(ddsd));
2492 ddsd.dwSize = sizeof(ddsd);
2493 ddsd.dwFlags = DDSD_CAPS;
2494 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2495 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
2496 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
2501 memset(entries, 0, sizeof(entries));
2502 entries[0].peRed = 0xff;
2503 entries[1].peGreen = 0xff;
2504 entries[2].peBlue = 0xff;
2506 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
2507 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2509 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
2513 hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
2514 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2516 p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
2518 color = getPixelColor_GDI(Surface1, 10, 10);
2519 ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
2520 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2521 GetRValue(color), GetGValue(color), GetBValue(color));
2523 memset(&ddbltfx, 0, sizeof(ddbltfx));
2524 ddbltfx.dwSize = sizeof(ddbltfx);
2525 U5(ddbltfx).dwFillColor = 0;
2526 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2527 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2529 color = getPixelColor_GDI(Surface1, 10, 10);
2530 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
2531 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
2532 GetRValue(color), GetGValue(color), GetBValue(color));
2534 memset(&ddbltfx, 0, sizeof(ddbltfx));
2535 ddbltfx.dwSize = sizeof(ddbltfx);
2536 U5(ddbltfx).dwFillColor = 1;
2537 hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2538 ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2540 color = getPixelColor_GDI(Surface1, 10, 10);
2541 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2542 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2543 GetRValue(color), GetGValue(color), GetBValue(color));
2545 memset (&ddsd, 0, sizeof (ddsd));
2546 ddsd.dwSize = sizeof (ddsd);
2547 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2550 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
2551 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2552 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2553 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2554 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2556 broken(hr == DDERR_INVALIDPIXELFORMAT) || /* VMware */
2557 broken(hr == DDERR_NODIRECTDRAWHW), /* VMware */
2558 "IDirectDraw_CreateSurface returned %08x\n", hr);
2559 if (FAILED(hr)) goto out;
2561 memset(entries, 0, sizeof(entries));
2562 for (i = 0; i < 256; i++) {
2563 entries[i].peBlue = i;
2565 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2566 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2568 hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
2569 ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2570 i = GetDIBColorTable(hdc, 0, 256, coltable);
2571 ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
2572 hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
2573 ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2575 ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
2577 p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 2);
2579 memset(entries, 0, sizeof(entries));
2580 entries[0].peRed = 0xff;
2581 entries[1].peGreen = 0xff;
2582 entries[2].peBlue = 0xff;
2583 entries[3].peRed = 0x80;
2584 hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2585 ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2587 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2588 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2590 color = getPixelColor_GDI(Surface1, 1, 1);
2591 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2592 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2593 GetRValue(color), GetGValue(color), GetBValue(color));
2595 /* Color keyed blit. */
2596 p8_surface_fill_rect(offscreen, 0, 0, 8, 8, 3);
2597 clrKey.dwColorSpaceLowValue = 3;
2598 clrKey.dwColorSpaceHighValue = 3;
2599 hr = IDirectDrawSurface_SetColorKey(offscreen, DDCKEY_SRCBLT, &clrKey);
2600 ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
2602 hr = IDirectDrawSurface_BltFast(Surface1, 100, 100, offscreen, NULL, DDBLTFAST_SRCCOLORKEY);
2603 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2605 color = getPixelColor_GDI(Surface1, 105, 105);
2606 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2607 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2608 GetRValue(color), GetGValue(color), GetBValue(color));
2610 color = getPixelColor_GDI(Surface1, 112, 112);
2611 ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2612 "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2613 GetRValue(color), GetGValue(color), GetBValue(color));
2620 memset(&ddbltfx, 0, sizeof(ddbltfx));
2621 ddbltfx.dwSize = sizeof(ddbltfx);
2622 ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 2;
2623 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2624 DDBLT_WAIT | DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2625 ok(hr==DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned: %x\n", hr);
2626 hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2627 DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2628 ok(hr==DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2630 color = getPixelColor_GDI(Surface1, 105, 205);
2631 ok(GetRValue(color) == 0x80 && GetGValue(color) == 0 && GetBValue(color) == 0,
2632 "got R %02X G %02X B %02X, expected R 80 G 00 B 00\n",
2633 GetRValue(color), GetGValue(color), GetBValue(color));
2635 color = getPixelColor_GDI(Surface1, 112, 212);
2636 ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2637 "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2638 GetRValue(color), GetGValue(color), GetBValue(color));
2640 /* Test blitting and locking patterns that are likely to trigger bugs in opengl renderer (p8
2641 surface conversion and uploading/downloading to/from opengl texture). Similar patterns (
2642 blitting front buffer areas to/from an offscreen surface mixed with locking) are used by C&C
2644 IDirectDrawSurface_Release(offscreen);
2646 memset (&ddsd, 0, sizeof (ddsd));
2647 ddsd.dwSize = sizeof (ddsd);
2648 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2650 ddsd.dwHeight = 480;
2651 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2652 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2653 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2654 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2655 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2656 ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
2658 if (FAILED(hr)) goto out;
2660 /* Test two times, first time front buffer has a palette and second time front buffer
2661 has no palette; the latter is somewhat contrived example, but an app could set
2662 front buffer palette later. */
2663 for (i2 = 0; i2 < 2; i2++) {
2665 hr = IDirectDrawSurface_SetPalette(Surface1, NULL);
2666 ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2669 memset(&ddsd, 0, sizeof(ddsd));
2670 ddsd.dwSize = sizeof(ddsd);
2671 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2672 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2674 for (i = 0; i < 256; i++) {
2675 unsigned x = (i % 128) * 4;
2676 unsigned y = (i / 128) * 4;
2677 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2679 for (i1 = 0; i1 < 4; i1++) {
2680 p[0] = p[1] = p[2] = p[3] = i;
2681 p += U1(ddsd).lPitch;
2685 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2686 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2688 hr = IDirectDrawSurface_BltFast(offscreen, 0, 0, Surface1, NULL, 0);
2689 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2691 /* This ensures offscreen surface contents will be downloaded to system memory. */
2692 memset(&ddsd, 0, sizeof(ddsd));
2693 ddsd.dwSize = sizeof(ddsd);
2694 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2695 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2696 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2697 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2699 /* Offscreen surface data will have to be converted and uploaded to texture. */
2704 hr = IDirectDrawSurface_BltFast(offscreen, 600, 400, Surface1, &rect, 0);
2705 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2707 /* This ensures offscreen surface contents will be downloaded to system memory. */
2708 memset(&ddsd, 0, sizeof(ddsd));
2709 ddsd.dwSize = sizeof(ddsd);
2710 hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2711 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2712 hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2713 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2715 hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2716 ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2718 memset(&ddsd, 0, sizeof(ddsd));
2719 ddsd.dwSize = sizeof(ddsd);
2720 hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2721 ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2725 for (i = 0; i < 256; i++) {
2726 unsigned x = (i % 128) * 4 + 1;
2727 unsigned y = (i / 128) * 4 + 1;
2728 BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2730 if (*p != i) differences++;
2733 hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2734 ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2736 ok(differences == 0, i2 == 0 ? "Pass 1. Unexpected front buffer contents after blit (%u differences)\n" :
2737 "Pass 2 (with NULL front buffer palette). Unexpected front buffer contents after blit (%u differences)\n",
2743 if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
2744 if(offscreen) IDirectDrawSurface_Release(offscreen);
2745 if(Surface1) IDirectDrawSurface_Release(Surface1);
2746 if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
2747 if(window) DestroyWindow(window);
2750 static void cubemap_test(IDirect3DDevice7 *device)
2753 IDirectDraw7 *ddraw;
2754 IDirectDrawSurface7 *cubemap, *surface;
2755 D3DDEVICEDESC7 d3dcaps;
2758 DDSURFACEDESC2 ddsd;
2761 static float quad[] = {
2762 -1.0, -1.0, 0.1, 1.0, 0.0, 0.0, /* Lower left */
2763 0.0, -1.0, 0.1, 1.0, 0.0, 0.0,
2764 -1.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2765 0.0, 0.0, 0.1, 1.0, 0.0, 0.0,
2767 0.0, -1.0, 0.1, 0.0, 1.0, 0.0, /* Lower right */
2768 1.0, -1.0, 0.1, 0.0, 1.0, 0.0,
2769 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2770 1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
2772 0.0, 0.0, 0.1, 0.0, 0.0, 1.0, /* upper right */
2773 1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
2774 0.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2775 1.0, 1.0, 0.1, 0.0, 0.0, 1.0,
2777 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, /* Upper left */
2778 0.0, 0.0, 0.1, -1.0, 0.0, 0.0,
2779 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2780 0.0, 1.0, 0.1, -1.0, 0.0, 0.0,
2783 memset(&DDBltFx, 0, sizeof(DDBltFx));
2784 DDBltFx.dwSize = sizeof(DDBltFx);
2786 memset(&d3dcaps, 0, sizeof(d3dcaps));
2787 hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
2788 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2789 if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2791 skip("No cubemap support\n");
2795 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2796 ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
2798 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2799 ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
2800 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
2801 ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
2802 IDirect3D7_Release(d3d);
2805 memset(&ddsd, 0, sizeof(ddsd));
2806 ddsd.dwSize = sizeof(ddsd);
2807 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2808 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2811 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2812 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
2813 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2814 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2815 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2816 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2817 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2819 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
2820 ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
2821 IDirectDraw7_Release(ddraw);
2824 U5(DDBltFx).dwFillColor = 0x00ff0000;
2825 hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2826 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2828 memset(&caps, 0, sizeof(caps));
2829 caps.dwCaps = DDSCAPS_TEXTURE;
2830 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
2831 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2832 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2833 U5(DDBltFx).dwFillColor = 0x0000ffff;
2834 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2835 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2837 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
2838 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2839 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2840 U5(DDBltFx).dwFillColor = 0x0000ff00;
2841 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2842 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2844 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
2845 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2846 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2847 U5(DDBltFx).dwFillColor = 0x000000ff;
2848 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2849 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2851 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2852 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2853 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2854 U5(DDBltFx).dwFillColor = 0x00ffff00;
2855 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2856 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2858 caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2859 hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2860 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2861 U5(DDBltFx).dwFillColor = 0x00ff00ff;
2862 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2863 ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2865 hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2866 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2867 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2868 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2869 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2870 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2872 hr = IDirect3DDevice7_BeginScene(device);
2873 ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2876 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2877 if (hr == DDERR_UNSUPPORTED || hr == DDERR_NODIRECTDRAWHW)
2880 win_skip("IDirect3DDevice7_DrawPrimitive is not completely implemented, colors won't be tested\n");
2881 hr = IDirect3DDevice7_EndScene(device);
2882 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2885 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2886 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
2887 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2888 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 8 * 6, 4, 0);
2889 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2890 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 12* 6, 4, 0);
2891 ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2893 hr = IDirect3DDevice7_EndScene(device);
2894 ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2896 hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2897 ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2899 color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2900 ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2901 color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2902 ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2903 color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2904 ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2905 color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2906 ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2909 hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2910 ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2911 IDirectDrawSurface7_Release(cubemap);
2914 /* This test tests depth clamping / clipping behaviour:
2915 * - With software vertex processing, depth values are clamped to the
2916 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2917 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2918 * same as regular vertices here.
2919 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2920 * Normal vertices are always clipped. Pretransformed vertices are
2921 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2922 * - The viewport's MinZ/MaxZ is irrelevant for this.
2924 static void depth_clamp_test(IDirect3DDevice7 *device)
2926 struct tvertex quad1[] =
2928 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2929 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
2930 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2931 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
2933 struct tvertex quad2[] =
2935 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2936 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2937 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2938 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2940 struct tvertex quad3[] =
2942 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2943 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
2944 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2945 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
2947 struct tvertex quad4[] =
2949 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2950 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
2951 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2952 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2954 struct vertex quad5[] =
2956 { -0.5f, 0.5f, 10.0f, 0xff14f914},
2957 { 0.5f, 0.5f, 10.0f, 0xff14f914},
2958 { -0.5f, -0.5f, 10.0f, 0xff14f914},
2959 { 0.5f, -0.5f, 10.0f, 0xff14f914},
2961 struct vertex quad6[] =
2963 { -1.0f, 0.5f, 10.0f, 0xfff91414},
2964 { 1.0f, 0.5f, 10.0f, 0xfff91414},
2965 { -1.0f, 0.25f, 10.0f, 0xfff91414},
2966 { 1.0f, 0.25f, 10.0f, 0xfff91414},
2980 hr = IDirect3DDevice7_SetViewport(device, &vp);
2981 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2983 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
2984 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2986 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
2987 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2988 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
2989 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2990 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZWRITEENABLE, TRUE);
2991 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2992 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
2993 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2995 hr = IDirect3DDevice7_BeginScene(device);
2996 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2998 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
2999 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3000 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad2, 4, 0);
3001 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3003 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3004 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3006 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad3, 4, 0);
3007 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3008 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad4, 4, 0);
3009 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3011 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
3012 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3014 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad5, 4, 0);
3015 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3017 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
3018 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3020 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad6, 4, 0);
3021 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
3023 hr = IDirect3DDevice7_EndScene(device);
3024 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3026 color = getPixelColor(device, 75, 75);
3027 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3028 color = getPixelColor(device, 150, 150);
3029 ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3030 color = getPixelColor(device, 320, 240);
3031 ok(color_match(color, 0x00002b7f, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3032 color = getPixelColor(device, 320, 330);
3033 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3034 color = getPixelColor(device, 320, 330);
3035 ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3039 hr = IDirect3DDevice7_SetViewport(device, &vp);
3040 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3043 static void DX1_BackBufferFlipTest(void)
3046 IDirectDraw *DirectDraw1 = NULL;
3047 IDirectDrawSurface *Primary = NULL;
3048 IDirectDrawSurface *Backbuffer = NULL;
3053 const DWORD white = 0xffffff;
3054 const DWORD red = 0xff0000;
3055 BOOL attached = FALSE;
3057 wc.lpfnWndProc = DefWindowProc;
3058 wc.lpszClassName = "DX1_BackBufferFlipTest_wc";
3060 window = CreateWindow("DX1_BackBufferFlipTest_wc", "DX1_BackBufferFlipTest",
3061 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3063 hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
3064 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
3065 if(FAILED(hr)) goto out;
3067 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3068 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
3069 if(FAILED(hr)) goto out;
3071 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
3073 /* 24 bit is fine too */
3074 hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
3076 ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
3081 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3082 ddsd.dwSize = sizeof(DDSURFACEDESC);
3083 ddsd.dwFlags = DDSD_CAPS;
3084 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3086 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Primary, NULL);
3087 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3089 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3090 ddsd.dwSize = sizeof(DDSURFACEDESC);
3091 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3092 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3094 ddsd.dwHeight = 480;
3095 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3096 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3097 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
3098 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
3099 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
3100 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
3102 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Backbuffer, NULL);
3103 ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
3104 if(FAILED(hr)) goto out;
3106 hr = IDirectDrawSurface_AddAttachedSurface(Primary, Backbuffer);
3107 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3108 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3109 if (FAILED(hr)) goto out;
3113 memset(&ddbltfx, 0, sizeof(ddbltfx));
3114 ddbltfx.dwSize = sizeof(ddbltfx);
3115 U5(ddbltfx).dwFillColor = red;
3116 hr = IDirectDrawSurface_Blt(Backbuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3117 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3119 U5(ddbltfx).dwFillColor = white;
3120 hr = IDirectDrawSurface_Blt(Primary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
3121 ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
3124 color = getPixelColor_GDI(Primary, 5, 5);
3125 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF,
3126 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3127 GetRValue(color), GetGValue(color), GetBValue(color));
3129 color = getPixelColor_GDI(Backbuffer, 5, 5);
3130 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3131 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3132 GetRValue(color), GetGValue(color), GetBValue(color));
3134 hr = IDirectDrawSurface_Flip(Primary, NULL, DDFLIP_WAIT);
3135 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3139 color = getPixelColor_GDI(Primary, 5, 5);
3140 ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3141 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3142 GetRValue(color), GetGValue(color), GetBValue(color));
3144 color = getPixelColor_GDI(Backbuffer, 5, 5);
3145 ok((GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF) ||
3146 broken(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0), /* broken driver */
3147 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3148 GetRValue(color), GetGValue(color), GetBValue(color));
3156 IDirectDrawSurface_DeleteAttachedSurface(Primary, 0, Backbuffer);
3157 IDirectDrawSurface_Release(Backbuffer);
3159 if (Primary) IDirectDrawSurface_Release(Primary);
3160 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
3161 if (window) DestroyWindow(window);
3168 if(!createObjects())
3170 skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
3174 /* Check for the reliability of the returned data */
3175 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3178 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3182 color = getPixelColor(Direct3DDevice, 1, 1);
3183 if(color !=0x00ff0000)
3185 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3189 hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3192 skip("Clear failed, can't assure correctness of the test results, skipping\n");
3196 color = getPixelColor(Direct3DDevice, 639, 479);
3197 if(color != 0x0000ddee)
3199 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3203 /* Now run the tests */
3204 blt_test(Direct3DDevice);
3205 depth_clamp_test(Direct3DDevice);
3206 lighting_test(Direct3DDevice);
3207 clear_test(Direct3DDevice);
3208 fog_test(Direct3DDevice);
3209 offscreen_test(Direct3DDevice);
3210 alpha_test(Direct3DDevice);
3211 rhw_zero_test(Direct3DDevice);
3212 cubemap_test(Direct3DDevice);
3214 releaseObjects(); /* release DX7 interfaces to test D3D1 */
3216 if(!D3D1_createObjects()) {
3217 skip("Cannot initialize D3D1, skipping\n");
3220 D3D1_TextureMapBlendTest();
3221 D3D1_ViewportClearTest();
3223 D3D1_releaseObjects();
3225 D3D3_ViewportClearTest();
3227 DX1_BackBufferFlipTest();