crypt32: Add additional path for Solaris 11 Express.
[wine] / dlls / ddraw / tests / visual.c
1 /*
2  * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
3  * Copyright (C) 2008 Alexander Dorofeyev
4  *
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.
9  *
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.
14  *
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
18  */
19
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
21
22 #include <assert.h>
23 #include "wine/test.h"
24 #include "ddraw.h"
25 #include "d3d.h"
26
27 static HWND window;
28 static IDirectDraw7        *DirectDraw;
29 static IDirectDrawSurface7 *Surface;
30 static IDirectDrawSurface7 *depth_buffer;
31 static IDirect3D7          *Direct3D;
32 static IDirect3DDevice7    *Direct3DDevice;
33
34 static IDirectDraw *DirectDraw1;
35 static IDirectDrawSurface *Surface1;
36 static IDirect3D *Direct3D1;
37 static IDirect3DDevice *Direct3DDevice1;
38 static IDirect3DExecuteBuffer *ExecuteBuffer;
39 static IDirect3DViewport *Viewport;
40
41 static BOOL refdevice = FALSE;
42
43 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
44
45 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
46 {
47     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
48     c1 >>= 8; c2 >>= 8;
49     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50     c1 >>= 8; c2 >>= 8;
51     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
52     c1 >>= 8; c2 >>= 8;
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     return TRUE;
55 }
56
57 static BOOL createObjects(void)
58 {
59     HRESULT hr;
60     HMODULE hmod = GetModuleHandleA("ddraw.dll");
61     WNDCLASS wc = {0};
62     DDSURFACEDESC2 ddsd;
63
64
65     if(!hmod) return FALSE;
66     pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
67     if(!pDirectDrawCreateEx) return FALSE;
68
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;
72
73     wc.lpfnWndProc = DefWindowProc;
74     wc.lpszClassName = "d3d7_test_wc";
75     RegisterClass(&wc);
76     window = CreateWindow("d3d7_test_wc", "d3d7_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
77
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);
82     if(FAILED(hr)) {
83         /* 24 bit is fine too */
84         hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 24, 0, 0);
85
86     }
87     ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "IDirectDraw7_SetDisplayMode failed with %08x\n", hr);
88     if(FAILED(hr)) {
89         /* use trace, the caller calls skip() */
90         trace("SetDisplayMode failed\n");
91         goto err;
92     }
93
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);
97
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
100      */
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;
108
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;
117     ddsd.dwWidth = 640;
118     ddsd.dwHeight = 480;
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;
122
123     hr = IDirectDrawSurface_AddAttachedSurface(Surface, depth_buffer);
124     ok(SUCCEEDED(hr), "AddAttachedSurface failed, hr %#x.\n", hr);
125     if (FAILED(hr)) goto err;
126
127     hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DTnLHalDevice, Surface, &Direct3DDevice);
128     if (FAILED(hr) || !Direct3DDevice) goto err;
129     return TRUE;
130
131     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);
138     return FALSE;
139 }
140
141 static void releaseObjects(void)
142 {
143     IDirect3DDevice7_Release(Direct3DDevice);
144     IDirect3D7_Release(Direct3D);
145     IDirectDrawSurface7_Release(depth_buffer);
146     IDirectDrawSurface7_Release(Surface);
147     IDirectDraw7_Release(DirectDraw);
148     DestroyWindow(window);
149 }
150
151 static DWORD getPixelColor(IDirect3DDevice7 *device, UINT x, UINT y)
152 {
153     DWORD ret;
154     HRESULT hr;
155     DDSURFACEDESC2 ddsd;
156     RECT rectToLock = {x, y, x+1, y+1};
157     IDirectDrawSurface7 *surf = NULL;
158
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
161      */
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;
166     ddsd.dwWidth = 640;
167     ddsd.dwHeight = 480;
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);
171     if(!surf)
172     {
173         trace("cannot create helper surface\n");
174         return 0xdeadbeef;
175     }
176
177     memset(&ddsd, 0, sizeof(ddsd));
178     ddsd.dwSize = sizeof(ddsd);
179     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
180
181     hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
182     ok(hr == DD_OK, "IDirectDrawSurface7_BltFast returned %08x\n", hr);
183     if(FAILED(hr))
184     {
185         trace("Cannot blit\n");
186         ret = 0xdeadbee;
187         goto out;
188     }
189
190     hr = IDirectDrawSurface7_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
191     if(FAILED(hr))
192     {
193         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
194         ret = 0xdeadbeec;
195         goto out;
196     }
197
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
200      */
201     ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
202     hr = IDirectDrawSurface7_Unlock(surf, NULL);
203     if(FAILED(hr))
204     {
205         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
206     }
207
208 out:
209     IDirectDrawSurface7_Release(surf);
210     return ret;
211 }
212
213 /*
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.
216  */
217 static void set_the_same_viewport_again(IDirect3DDevice7 *device)
218 {
219     D3DVIEWPORT7 vp = {0};
220     HRESULT hr;
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);
225     return;
226 }
227
228 struct vertex
229 {
230     float x, y, z;
231     DWORD diffuse;
232 };
233
234 struct tvertex
235 {
236     float x, y, z, w;
237     DWORD diffuse;
238 };
239
240 struct nvertex
241 {
242     float x, y, z;
243     float nx, ny, nz;
244     DWORD diffuse;
245 };
246
247 static void lighting_test(IDirect3DDevice7 *device)
248 {
249     HRESULT hr;
250     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
251     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
252     DWORD color;
253
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 };
258
259     struct vertex unlitquad[] =
260     {
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},
265     };
266     struct vertex litquad[] =
267     {
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},
272     };
273     struct nvertex unlitnquad[] =
274     {
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},
279     };
280     struct nvertex litnquad[] =
281     {
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},
286     };
287     WORD Indices[] = {0, 1, 2, 2, 3, 0};
288
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);
291
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);
313
314     hr = IDirect3DDevice7_BeginScene(device);
315     ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
316     if(hr == D3D_OK)
317     {
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);
324
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);
330
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);
336
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);
342
343         IDirect3DDevice7_EndScene(device);
344         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
345     }
346
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);
355
356     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
357     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
358 }
359
360 static void clear_test(IDirect3DDevice7 *device)
361 {
362     /* Tests the correctness of clearing parameters */
363     HRESULT hr;
364     D3DRECT rect[2];
365     D3DRECT rect_negneg;
366     DWORD color;
367
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);
370
371     /* Positive x, negative y */
372     U1(rect[0]).x1 = 0;
373     U2(rect[0]).y1 = 480;
374     U3(rect[0]).x2 = 320;
375     U4(rect[0]).y2 = 240;
376
377     /* Positive x, positive y */
378     U1(rect[1]).x1 = 0;
379     U2(rect[1]).y1 = 0;
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
384      */
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);
387
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);
395
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);
404 }
405
406 struct sVertex {
407     float x, y, z;
408     DWORD diffuse;
409     DWORD specular;
410 };
411
412 struct sVertexT {
413     float x, y, z, rhw;
414     DWORD diffuse;
415     DWORD specular;
416 };
417
418 static void fog_test(IDirect3DDevice7 *device)
419 {
420     HRESULT hr;
421     DWORD color;
422     float start = 0.0, end = 1.0;
423     D3DDEVICEDESC7 caps;
424
425     /* Gets full z based fog with linear fog, no fog with specular color */
426     struct sVertex unstransformed_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  },
431     };
432     /* Ok, I am too lazy to deal with transform matrices */
433     struct sVertex unstransformed_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  },
438     };
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.
441      */
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  },
447     };
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  },
453     };
454     WORD Indices[] = {0, 1, 2, 2, 3, 0};
455
456     memset(&caps, 0, sizeof(caps));
457     hr = IDirect3DDevice7_GetCaps(device, &caps);
458     ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
459     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
460     ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr);
461
462     /* Setup initial states: No lighting, fog on, fog color */
463     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
464     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
465     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE);
466     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
467     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */);
468     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
469
470     /* First test: Both table fog and vertex fog off */
471     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
472     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
473     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
474     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
475
476     /* Start = 0, end = 1. Should be default, but set them */
477     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start));
478     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
479     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end));
480     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
481
482     if(IDirect3DDevice7_BeginScene(device) == D3D_OK)
483     {
484         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
485         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
486                                                    unstransformed_1, 4, Indices, 6, 0);
487         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
488
489         /* That makes it use the Z value */
490         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
491         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
492         /* Untransformed, vertex fog != none (or table fog != none):
493          * Use the Z value as input into the equation
494          */
495         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
496                                                    unstransformed_2, 4, Indices, 6, 0);
497         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
498
499         /* transformed verts */
500         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
501         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
502         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
503                                                    transformed_1, 4, Indices, 6, 0);
504         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
505
506         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
507         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
508         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
509          * equation
510          */
511         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
512                                                    transformed_2, 4, Indices, 6, 0);
513         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
514
515         hr = IDirect3DDevice7_EndScene(device);
516         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
517     }
518     else
519     {
520         ok(FALSE, "BeginScene failed\n");
521     }
522
523     color = getPixelColor(device, 160, 360);
524     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
525     color = getPixelColor(device, 160, 120);
526     ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
527     color = getPixelColor(device, 480, 120);
528     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
529     if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
530     {
531         color = getPixelColor(device, 480, 360);
532         ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
533     }
534     else
535     {
536         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
537          * The settings above result in no fogging with vertex fog
538          */
539         color = getPixelColor(device, 480, 120);
540         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
541         trace("Info: Table fog not supported by this device\n");
542     }
543
544     /* Turn off the fog master switch to avoid confusing other tests */
545     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
546     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
547 }
548
549 static void blt_test(IDirect3DDevice7 *device)
550 {
551     IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
552     DDSURFACEDESC2 ddsd;
553     HRESULT hr;
554
555     memset(&ddsd, 0, sizeof(ddsd));
556     ddsd.dwSize = sizeof(ddsd);
557     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
558     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
559     ddsd.dwWidth = 640;
560     ddsd.dwHeight = 480;
561     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
562     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
563     ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
564
565     /* Offscreen blits with the same source as destination */
566     if(SUCCEEDED(hr))
567     {
568         RECT src_rect, dst_rect;
569
570         /* Blit the whole surface to itself */
571         hr = IDirectDrawSurface_Blt(offscreen, NULL, offscreen, NULL, 0, NULL);
572         ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
573
574         /* Overlapped blit */
575         dst_rect.left = 0; dst_rect.right = 480;
576         dst_rect.top = 0; dst_rect.bottom = 480;
577         src_rect.left = 160; src_rect.right = 640;
578         src_rect.top = 0; src_rect.bottom = 480;
579         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
580         ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
581
582         /* Overlapped blit, flip-y through source rectangle (not allowed) */
583         dst_rect.left = 0; dst_rect.right = 480;
584         dst_rect.top = 0; dst_rect.bottom = 480;
585         src_rect.left = 160; src_rect.right = 640;
586         src_rect.top = 480; src_rect.bottom = 0;
587         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
588         ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface7_Blt returned %08x\n", hr);
589
590         /* Overlapped blit, with shrinking in x */
591         dst_rect.left = 0; dst_rect.right = 480;
592         dst_rect.top = 0; dst_rect.bottom = 480;
593         src_rect.left = 160; src_rect.right = 480;
594         src_rect.top = 0; src_rect.bottom = 480;
595         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, offscreen, &src_rect, 0, NULL);
596         ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
597     }
598
599     hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
600     ok(hr == D3D_OK, "Unable to obtain a surface pointer to the backbuffer, hr = %08x\n", hr);
601
602     /* backbuffer ==> texture blits */
603     if(SUCCEEDED(hr) && offscreen)
604     {
605         RECT src_rect, dst_rect;
606
607         /* backbuffer ==> texture, src_rect=NULL, dst_rect=NULL, no scaling */
608         hr = IDirectDrawSurface_Blt(offscreen, NULL, backbuffer, NULL, 0, NULL);
609         ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
610
611         /* backbuffer ==> texture, full surface blits, no scaling */
612         dst_rect.left = 0; dst_rect.right = 640;
613         dst_rect.top = 0; dst_rect.bottom = 480;
614         src_rect.left = 0; src_rect.right = 640;
615         src_rect.top = 0; src_rect.bottom = 480;
616         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
617         ok(hr == DD_OK, "fullscreen Blt from backbuffer => texture failed with hr = %08x\n", hr);
618
619         /* backbuffer ==> texture, flip in y-direction through source rectangle, no scaling (allowed) */
620         dst_rect.left = 0; dst_rect.right = 640;
621         dst_rect.top = 480; dst_rect.top = 0;
622         src_rect.left = 0; src_rect.right = 640;
623         src_rect.top = 0; src_rect.bottom = 480;
624         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
625         ok(hr == DD_OK, "backbuffer => texture flip-y src_rect failed with hr = %08x\n", hr);
626
627         /* backbuffer ==> texture, flip in x-direction through source rectangle, no scaling (not allowed) */
628         dst_rect.left = 640; dst_rect.right = 0;
629         dst_rect.top = 0; dst_rect.top = 480;
630         src_rect.left = 0; src_rect.right = 640;
631         src_rect.top = 0; src_rect.bottom = 480;
632         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
633         ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x src_rect failed with hr = %08x\n", hr);
634
635         /* backbuffer ==> texture, flip in y-direction through destination rectangle (not allowed) */
636         dst_rect.left = 0; dst_rect.right = 640;
637         dst_rect.top = 0; dst_rect.top = 480;
638         src_rect.left = 0; src_rect.right = 640;
639         src_rect.top = 480; src_rect.bottom = 0;
640         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
641         ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-y dst_rect failed with hr = %08x\n", hr);
642
643         /* backbuffer ==> texture, flip in x-direction through destination rectangle, no scaling (not allowed) */
644         dst_rect.left = 0; dst_rect.right = 640;
645         dst_rect.top = 0; dst_rect.top = 480;
646         src_rect.left = 640; src_rect.right = 0;
647         src_rect.top = 0; src_rect.bottom = 480;
648         hr = IDirectDrawSurface_Blt(offscreen, &dst_rect, backbuffer, &src_rect, 0, NULL);
649         ok(hr == DDERR_INVALIDRECT, "backbuffer => texture flip-x dst_rect failed with hr = %08x\n", hr);
650     }
651
652     if(offscreen) IDirectDrawSurface7_Release(offscreen);
653     if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
654 }
655
656 static void offscreen_test(IDirect3DDevice7 *device)
657 {
658     HRESULT hr;
659     IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
660     DWORD color;
661     DDSURFACEDESC2 ddsd;
662
663     static float quad[][5] = {
664         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
665         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
666         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
667         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
668     };
669
670     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
671     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
672
673     memset(&ddsd, 0, sizeof(ddsd));
674     ddsd.dwSize = sizeof(ddsd);
675     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
676     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
677     ddsd.dwWidth = 128;
678     ddsd.dwHeight = 128;
679     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
680     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
681     ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
682     if(!offscreen) {
683         goto out;
684     }
685
686     hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
687     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
688     if(!backbuffer) {
689         goto out;
690     }
691
692     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
693     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
694     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
695     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
696     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
697     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
698     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
699     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
700     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
701     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
702
703     if (refdevice) {
704         win_skip("Tests would crash on W2K with a refdevice\n");
705         goto out;
706     }
707
708     if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
709         hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
710         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
711         hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
712         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
713
714         /* Draw without textures - Should result in a white quad */
715         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
716         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
717
718         hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
719         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
720         set_the_same_viewport_again(device);
721
722         hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
723         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
724
725         /* This time with the texture */
726         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
727         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
728
729         IDirect3DDevice7_EndScene(device);
730     }
731
732     /* Center quad - should be white */
733     color = getPixelColor(device, 320, 240);
734     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
735     /* Some quad in the cleared part of the texture */
736     color = getPixelColor(device, 170, 240);
737     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
738     /* Part of the originally cleared back buffer */
739     color = getPixelColor(device, 10, 10);
740     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
741     if(0) {
742         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
743          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
744          * the offscreen rendering mode this test would succeed or fail
745          */
746         color = getPixelColor(device, 10, 470);
747         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
748     }
749
750 out:
751     hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
752     ok(SUCCEEDED(hr), "IDirect3DDevice7_SetTexture returned %#x.\n", hr);
753
754     /* restore things */
755     if(backbuffer) {
756         hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
757         ok(SUCCEEDED(hr), "IDirect3DDevice7_SetRenderTarget returned %#x.\n", hr);
758         IDirectDrawSurface7_Release(backbuffer);
759     }
760     if(offscreen) {
761         IDirectDrawSurface7_Release(offscreen);
762     }
763 }
764
765 static void alpha_test(IDirect3DDevice7 *device)
766 {
767     HRESULT hr;
768     IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
769     DWORD color, red, green, blue;
770     DDSURFACEDESC2 ddsd;
771
772     struct vertex quad1[] =
773     {
774         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
775         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
776         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
777         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
778     };
779     struct vertex quad2[] =
780     {
781         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
782         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
783         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
784         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
785     };
786     static float composite_quad[][5] = {
787         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
788         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
789         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
790         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
791     };
792
793     /* Clear the render target with alpha = 0.5 */
794     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
795     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
796
797     memset(&ddsd, 0, sizeof(ddsd));
798     ddsd.dwSize = sizeof(ddsd);
799     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
800     ddsd.dwWidth = 128;
801     ddsd.dwHeight = 128;
802     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
803     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
804     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount      = 32;
805     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
806     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
807     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask         = 0x000000ff;
808     U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask  = 0xff000000;
809     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
810     ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
811     if(!offscreen) {
812         goto out;
813     }
814     hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
815     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
816     if(!backbuffer) {
817         goto out;
818     }
819
820     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
821     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
822     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
823     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
824     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
825     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
826     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
827     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
828
829     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
830     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
831
832     if (refdevice) {
833         win_skip("Tests would crash on W2K with a refdevice\n");
834         goto out;
835     }
836
837     if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
838
839         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
840          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
841          * the input alpha
842          *
843          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
844          * They give essentially ZERO and ONE blend factors
845          */
846         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
847         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
848         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
849         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
850         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
851         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
852
853         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
854         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
855         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
856         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
857         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
858         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
859
860         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
861          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
862          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
863          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
864          * vertices
865          */
866         hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
867         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
868         hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
869         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
870
871         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
872         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
873         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
874         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
875         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
876         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
877
878         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
879         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
880         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
881         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
882         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
883         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
884
885         hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
886         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
887         set_the_same_viewport_again(device);
888
889         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
890          * Disable alpha blending for the final composition
891          */
892         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
893         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
894
895         hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
896         ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
897         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
898         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
899         hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
900         ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
901
902         hr = IDirect3DDevice7_EndScene(device);
903         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
904     }
905
906     color = getPixelColor(device, 160, 360);
907     red =   (color & 0x00ff0000) >> 16;
908     green = (color & 0x0000ff00) >>  8;
909     blue =  (color & 0x000000ff);
910     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
911        "SRCALPHA on frame buffer returned color 0x%08x, expected 0x00bf4000\n", color);
912
913     color = getPixelColor(device, 160, 120);
914     red =   (color & 0x00ff0000) >> 16;
915     green = (color & 0x0000ff00) >>  8;
916     blue =  (color & 0x000000ff);
917     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
918        "DSTALPHA on frame buffer returned color 0x%08x, expected 0x000000ff\n", color);
919
920     color = getPixelColor(device, 480, 360);
921     red =   (color & 0x00ff0000) >> 16;
922     green = (color & 0x0000ff00) >>  8;
923     blue =  (color & 0x000000ff);
924     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
925        "SRCALPHA on texture returned color 0x%08x, expected 0x00bf4000\n", color);
926
927     color = getPixelColor(device, 480, 120);
928     red =   (color & 0x00ff0000) >> 16;
929     green = (color & 0x0000ff00) >>  8;
930     blue =  (color & 0x000000ff);
931     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
932        "DSTALPHA on texture returned color 0x%08x, expected 0x00800080\n", color);
933
934     out:
935     if(offscreen) IDirectDrawSurface7_Release(offscreen);
936     if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
937 }
938
939 static void rhw_zero_test(IDirect3DDevice7 *device)
940 {
941 /* Test if it will render a quad correctly when vertex rhw = 0 */
942     HRESULT hr;
943     DWORD color;
944
945     struct {
946         float x, y, z;
947         float rhw;
948         DWORD diffuse;
949         } quad1[] =
950     {
951         {0, 100, 0, 0, 0xffffffff},
952         {0, 0, 0, 0, 0xffffffff},
953         {100, 100, 0, 0, 0xffffffff},
954         {100, 0, 0, 0, 0xffffffff},
955     };
956
957     /* Clear to black */
958     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
959     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
960
961     hr = IDirect3DDevice7_BeginScene(device);
962     ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
963
964     if (SUCCEEDED(hr)) {
965         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
966         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
967
968         hr = IDirect3DDevice7_EndScene(device);
969         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
970     }
971
972     color = getPixelColor(device, 5, 5);
973     ok(color == 0xffffff ||
974        broken(color == 0), /* VMware */
975        "Got color %08x, expected 00ffffff\n", color);
976
977     color = getPixelColor(device, 105, 105);
978     ok(color == 0, "Got color %08x, expected 00000000\n", color);
979 }
980
981 static BOOL D3D1_createObjects(void)
982 {
983     WNDCLASS wc = {0};
984     HRESULT hr;
985     DDSURFACEDESC ddsd;
986     D3DEXECUTEBUFFERDESC exdesc;
987     D3DVIEWPORT vp_data;
988
989     /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
990     hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
991
992     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
993     if (FAILED(hr)) {
994         return FALSE;
995     }
996
997     wc.lpfnWndProc = DefWindowProc;
998     wc.lpszClassName = "texturemapblend_test_wc";
999     RegisterClass(&wc);
1000     window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1001
1002     hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1003     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1004     if(FAILED(hr)) {
1005         return FALSE;
1006     }
1007
1008     hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
1009     if(FAILED(hr)) {
1010         /* 24 bit is fine too */
1011         hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
1012     }
1013     ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1014     if (FAILED(hr)) {
1015         return FALSE;
1016     }
1017
1018     hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1019     ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1020     if (FAILED(hr)) {
1021         return FALSE;
1022     }
1023
1024     memset(&ddsd, 0, sizeof(ddsd));
1025     ddsd.dwSize = sizeof(ddsd);
1026     ddsd.dwFlags = DDSD_CAPS;
1027     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
1028     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1029     ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1030     if (FAILED(hr)) {
1031         return FALSE;
1032     }
1033
1034     hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
1035     if(FAILED(hr)) {
1036         trace("Creating a HAL device failed, trying Ref\n");
1037         hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
1038     }
1039     ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
1040     if(FAILED(hr)) {
1041         return FALSE;
1042     }
1043
1044     hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1045     ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1046     if (FAILED(hr)) {
1047         return FALSE;
1048     }
1049
1050     hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1051     ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1052     hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1053     ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1054     vp_data.dwSize = sizeof(vp_data);
1055     vp_data.dwX = 0;
1056     vp_data.dwY = 0;
1057     vp_data.dwWidth = 640;
1058     vp_data.dwHeight = 480;
1059     vp_data.dvScaleX = 1;
1060     vp_data.dvScaleY = 1;
1061     vp_data.dvMaxX = 640;
1062     vp_data.dvMaxY = 480;
1063     vp_data.dvMinZ = 0;
1064     vp_data.dvMaxZ = 1;
1065     hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1066     ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1067
1068     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1069     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1070     exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1071     exdesc.dwBufferSize = 512;
1072     exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
1073     hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
1074     ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
1075     if (FAILED(hr)) {
1076         return FALSE;
1077     }
1078
1079     return TRUE;
1080 }
1081
1082 static void D3D1_releaseObjects(void)
1083 {
1084     if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1085     if(Surface1) IDirectDrawSurface_Release(Surface1);
1086     if(Viewport) IDirect3DViewport_Release(Viewport);
1087     if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1088     if(Direct3D1) IDirect3D_Release(Direct3D1);
1089     if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1090     if(window) DestroyWindow(window);
1091 }
1092
1093 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
1094 {
1095     DWORD ret;
1096     HRESULT hr;
1097     DDSURFACEDESC ddsd;
1098     RECT rectToLock = {x, y, x+1, y+1};
1099     IDirectDrawSurface *surf = NULL;
1100
1101     /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
1102      * to an offscreen surface and lock it instead of the front buffer
1103      */
1104     memset(&ddsd, 0, sizeof(ddsd));
1105     ddsd.dwSize = sizeof(ddsd);
1106     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1107     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
1108     ddsd.dwWidth = 640;
1109     ddsd.dwHeight = 480;
1110     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
1111     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
1112     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
1113     if(!surf)
1114     {
1115         trace("cannot create helper surface\n");
1116         return 0xdeadbeef;
1117     }
1118
1119     memset(&ddsd, 0, sizeof(ddsd));
1120     ddsd.dwSize = sizeof(ddsd);
1121     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1122
1123     hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
1124     ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
1125     if(FAILED(hr))
1126     {
1127         trace("Cannot blit\n");
1128         ret = 0xdeadbee;
1129         goto out;
1130     }
1131
1132     hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
1133     if(FAILED(hr))
1134     {
1135         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
1136         ret = 0xdeadbeec;
1137         goto out;
1138     }
1139
1140     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
1141      * really important for these tests
1142      */
1143     ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
1144     hr = IDirectDrawSurface_Unlock(surf, NULL);
1145     if(FAILED(hr))
1146     {
1147         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
1148     }
1149
1150 out:
1151     IDirectDrawSurface_Release(surf);
1152     return ret;
1153 }
1154
1155 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
1156                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
1157                          ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
1158                          ((D3DINSTRUCTION*)(ptr))->wCount = count;\
1159                          ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1160
1161 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
1162                          U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
1163                          U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
1164                          ptr = ((D3DSTATE*)(ptr))+1; } while (0)
1165
1166 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
1167                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
1168                          ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
1169                          ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1170                          ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1171                          ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1172                          ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1173                          ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1174                          ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1175                          ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1176                          ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1177
1178 #define EXEBUF_END(ptr) do {\
1179                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1180                          ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1181                          ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1182                          ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1183
1184 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1185                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1186                          ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1187                          ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1188                          ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1189                          U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1190                          U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1191                          U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1192                          ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1193                          ptr = ((D3DTRIANGLE*)ptr)+1;\
1194                          U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1195                          U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1196                          U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1197                          ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1198                          ptr = ((D3DTRIANGLE*)(ptr))+1;\
1199                         } while (0)
1200
1201 static HRESULT CALLBACK TextureFormatEnumCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext)
1202 {
1203     if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1204         *(BOOL*)lpContext = TRUE;
1205     }
1206
1207     return DDENUMRET_OK;
1208 }
1209
1210 static void D3D1_TextureMapBlendTest(void)
1211 {
1212     HRESULT hr;
1213     DDSURFACEDESC ddsd;
1214     D3DEXECUTEBUFFERDESC exdesc;
1215     D3DEXECUTEDATA exdata;
1216     DDBLTFX ddbltfx;
1217     RECT rect = { 0, 0, 64, 128 };
1218     DWORD color, red, blue, green;
1219     void *exe_buffer_ptr;
1220     DWORD exe_length;
1221     D3DTEXTUREHANDLE htex;
1222     DDCOLORKEY clrKey;
1223     IDirectDrawSurface *TexSurface = NULL;
1224     IDirect3DTexture *Texture = NULL;
1225     IDirectDrawPalette *Palette = NULL;
1226     PALETTEENTRY table1[256];
1227     BOOL p8_textures_supported = FALSE;
1228
1229     struct {
1230         float x, y, z;
1231         float rhw;
1232         DWORD diffuse;
1233         DWORD specular;
1234         float tu, tv;
1235         } test1_quads[] =
1236     {
1237           {0.0f,   0.0f,     0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1238           {640.0f, 0.0f,     0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1239           {640.0f, 240.0f,   0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1240           {0.0f,   240.0f,   0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1241           {0.0f,   240.0f,   0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1242           {640.0f, 240.0f,   0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1243           {640.0f, 480.0f,   0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1244           {0.0f,   480.0f,   0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1245     },  test2_quads[] =
1246           {
1247           {0.0f,   0.0f,     0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1248           {640.0f, 0.0f,     0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1249           {640.0f, 240.0f,   0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1250           {0.0f,   240.0f,   0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1251           {0.0f,   240.0f,   0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1252           {640.0f, 240.0f,   0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1253           {640.0f, 480.0f,   0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1254           {0.0f,   480.0f,   0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1255     };
1256
1257     /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1258     memset (&ddsd, 0, sizeof (ddsd));
1259     ddsd.dwSize = sizeof (ddsd);
1260     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1261     ddsd.dwHeight = 128;
1262     ddsd.dwWidth = 128;
1263     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1264     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1265     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1266     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
1267     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
1268     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
1269     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
1270     U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask  = 0xff000000;
1271     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1272     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1273     if (FAILED(hr)) {
1274         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1275         goto out;
1276     }
1277
1278     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1279                 (void *)&Texture);
1280     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1281     if (FAILED(hr)) {
1282         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1283         goto out;
1284     }
1285
1286     memset(&ddbltfx, 0, sizeof(ddbltfx));
1287     ddbltfx.dwSize = sizeof(ddbltfx);
1288     U5(ddbltfx).dwFillColor = 0;
1289     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1290     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1291
1292     U5(ddbltfx).dwFillColor = 0xff0000ff;
1293     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1294     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1295     U5(ddbltfx).dwFillColor = 0x800000ff;
1296     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1297     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1298
1299     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1300     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1301     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1302     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1303     if (FAILED(hr)) {
1304         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1305         goto out;
1306     }
1307
1308     memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1309
1310     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1311
1312     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1313
1314     EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1315     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE,         D3DCULL_NONE,              exe_buffer_ptr);
1316     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE,          FALSE,                     exe_buffer_ptr);
1317     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE,        FALSE,                     exe_buffer_ptr);
1318     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE,   FALSE,                     exe_buffer_ptr);
1319     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG,       D3DFILTER_NEAREST,         exe_buffer_ptr);
1320     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN,       D3DFILTER_NEAREST,         exe_buffer_ptr);
1321     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE  ,       D3DFILL_SOLID,             exe_buffer_ptr);
1322     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND,         D3DBLEND_SRCALPHA,         exe_buffer_ptr);
1323     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND,        D3DBLEND_INVSRCALPHA,      exe_buffer_ptr);
1324     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE,                      exe_buffer_ptr);
1325     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND,  D3DTBLEND_MODULATE,        exe_buffer_ptr);
1326     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1327     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1328     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1329
1330     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1331     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1332
1333     EXEBUF_END(exe_buffer_ptr);
1334
1335     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1336
1337     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1338     if (FAILED(hr)) {
1339         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1340     }
1341
1342     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1343     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1344     exdata.dwVertexCount = 8;
1345     exdata.dwInstructionOffset = 256;
1346     exdata.dwInstructionLength = exe_length;
1347     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1348     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1349
1350     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1351     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1352
1353     if (SUCCEEDED(hr)) {
1354         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1355         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1356         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1357         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1358     }
1359
1360     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1361     red =   (color & 0x00ff0000) >> 16;
1362     green = (color & 0x0000ff00) >>  8;
1363     blue =  (color & 0x000000ff);
1364     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1365
1366     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1367     red =   (color & 0x00ff0000) >> 16;
1368     green = (color & 0x0000ff00) >>  8;
1369     blue =  (color & 0x000000ff);
1370     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1371
1372     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1373     red =   (color & 0x00ff0000) >> 16;
1374     green = (color & 0x0000ff00) >>  8;
1375     blue =  (color & 0x000000ff);
1376     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1377
1378     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1379     red =   (color & 0x00ff0000) >> 16;
1380     green = (color & 0x0000ff00) >>  8;
1381     blue =  (color & 0x000000ff);
1382     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1383
1384     /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1385     if(Texture) IDirect3DTexture_Release(Texture);
1386     Texture = NULL;
1387     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1388     TexSurface = NULL;
1389
1390     memset (&ddsd, 0, sizeof (ddsd));
1391     ddsd.dwSize = sizeof (ddsd);
1392     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1393     ddsd.dwHeight = 128;
1394     ddsd.dwWidth = 128;
1395     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1396     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1397     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1398     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
1399     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
1400     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
1401     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
1402
1403     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1404     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1405     if (FAILED(hr)) {
1406         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1407         goto out;
1408     }
1409
1410     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1411                 (void *)&Texture);
1412     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1413     if (FAILED(hr)) {
1414         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1415         goto out;
1416     }
1417
1418     memset(&ddbltfx, 0, sizeof(ddbltfx));
1419     ddbltfx.dwSize = sizeof(ddbltfx);
1420     U5(ddbltfx).dwFillColor = 0;
1421     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1422     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1423
1424     U5(ddbltfx).dwFillColor = 0xff0000ff;
1425     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1426     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1427     U5(ddbltfx).dwFillColor = 0x800000ff;
1428     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1429     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1430
1431     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1432     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1433     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1434     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1435     if (FAILED(hr)) {
1436         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1437         goto out;
1438     }
1439
1440     memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1441
1442     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1443
1444     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1445
1446     EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1447     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1448     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1449     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1450
1451     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1452     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1453
1454     EXEBUF_END(exe_buffer_ptr);
1455
1456     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1457
1458     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1459     if (FAILED(hr)) {
1460         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1461     }
1462
1463     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1464     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1465     exdata.dwVertexCount = 8;
1466     exdata.dwInstructionOffset = 256;
1467     exdata.dwInstructionLength = exe_length;
1468     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1469     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1470
1471     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1472     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1473
1474     if (SUCCEEDED(hr)) {
1475         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1476         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1477         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1478         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1479     }
1480
1481     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1482     red =   (color & 0x00ff0000) >> 16;
1483     green = (color & 0x0000ff00) >>  8;
1484     blue =  (color & 0x000000ff);
1485     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1486
1487     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1488     red =   (color & 0x00ff0000) >> 16;
1489     green = (color & 0x0000ff00) >>  8;
1490     blue =  (color & 0x000000ff);
1491     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1492
1493     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1494     red =   (color & 0x00ff0000) >> 16;
1495     green = (color & 0x0000ff00) >>  8;
1496     blue =  (color & 0x000000ff);
1497     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1498
1499     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1500     red =   (color & 0x00ff0000) >> 16;
1501     green = (color & 0x0000ff00) >>  8;
1502     blue =  (color & 0x000000ff);
1503     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1504
1505     /* 3) Test RGB - should multiply color components from diffuse color and texture */
1506     if(Texture) IDirect3DTexture_Release(Texture);
1507     Texture = NULL;
1508     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1509     TexSurface = NULL;
1510
1511     memset (&ddsd, 0, sizeof (ddsd));
1512     ddsd.dwSize = sizeof (ddsd);
1513     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1514     ddsd.dwHeight = 128;
1515     ddsd.dwWidth = 128;
1516     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1517     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1518     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1519     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
1520     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
1521     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
1522     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
1523     U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask  = 0xff000000;
1524     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1525     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1526     if (FAILED(hr)) {
1527         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1528         goto out;
1529     }
1530
1531     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1532                 (void *)&Texture);
1533     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1534     if (FAILED(hr)) {
1535         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1536         goto out;
1537     }
1538
1539     memset(&ddbltfx, 0, sizeof(ddbltfx));
1540     ddbltfx.dwSize = sizeof(ddbltfx);
1541     U5(ddbltfx).dwFillColor = 0;
1542     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1543     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1544
1545     U5(ddbltfx).dwFillColor = 0x00ffffff;
1546     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1547     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1548     U5(ddbltfx).dwFillColor = 0x00ffff80;
1549     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1550     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1551
1552     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1553     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1554     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1555     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1556     if (FAILED(hr)) {
1557         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1558         goto out;
1559     }
1560
1561     memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1562
1563     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1564
1565     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1566
1567     EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1568     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1569     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1570     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1571     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1572
1573     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1574     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1575
1576     EXEBUF_END(exe_buffer_ptr);
1577
1578     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1579
1580     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1581     if (FAILED(hr)) {
1582         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1583     }
1584
1585     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1586     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1587     exdata.dwVertexCount = 8;
1588     exdata.dwInstructionOffset = 256;
1589     exdata.dwInstructionLength = exe_length;
1590     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1591     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1592
1593     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1594     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1595
1596     if (SUCCEEDED(hr)) {
1597         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1598         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1599         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1600         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1601     }
1602
1603     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1604     red =   (color & 0x00ff0000) >> 16;
1605     green = (color & 0x0000ff00) >>  8;
1606     blue =  (color & 0x000000ff);
1607     ok(red == 0xff &&  green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1608
1609     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1610     red =   (color & 0x00ff0000) >> 16;
1611     green = (color & 0x0000ff00) >>  8;
1612     blue =  (color & 0x000000ff);
1613     ok(red == 0xff &&  green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1614
1615     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1616     red =   (color & 0x00ff0000) >> 16;
1617     green = (color & 0x0000ff00) >>  8;
1618     blue =  (color & 0x000000ff);
1619     ok(red >= 0x7e && red <= 0x82 &&  green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1620
1621     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1622     red =   (color & 0x00ff0000) >> 16;
1623     green = (color & 0x0000ff00) >>  8;
1624     blue =  (color & 0x000000ff);
1625     ok(red >= 0x7e && red <= 0x82 &&  green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1626
1627     /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1628     if(Texture) IDirect3DTexture_Release(Texture);
1629     Texture = NULL;
1630     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1631     TexSurface = NULL;
1632
1633     memset (&ddsd, 0, sizeof (ddsd));
1634     ddsd.dwSize = sizeof (ddsd);
1635     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1636     ddsd.dwHeight = 128;
1637     ddsd.dwWidth = 128;
1638     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1639     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1640     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1641     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 16;
1642     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0xf800;
1643     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x07e0;
1644     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x001f;
1645
1646     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1647     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1648     if (FAILED(hr)) {
1649         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1650         goto out;
1651     }
1652
1653     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1654                 (void *)&Texture);
1655     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1656     if (FAILED(hr)) {
1657         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1658         goto out;
1659     }
1660
1661     memset(&ddbltfx, 0, sizeof(ddbltfx));
1662     ddbltfx.dwSize = sizeof(ddbltfx);
1663     U5(ddbltfx).dwFillColor = 0;
1664     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1665     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1666     U5(ddbltfx).dwFillColor = 0xf800;
1667     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1668     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1669     U5(ddbltfx).dwFillColor = 0x001f;
1670     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1671     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1672
1673     clrKey.dwColorSpaceLowValue = 0x001f;
1674     clrKey.dwColorSpaceHighValue = 0x001f;
1675     hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1676     ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1677
1678     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1679     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1680     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1681     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1682     if (FAILED(hr)) {
1683         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1684         goto out;
1685     }
1686
1687     memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1688
1689     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1690
1691     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1692
1693     EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1694     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1695     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1696     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1697     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1698
1699     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1700     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1701
1702     EXEBUF_END(exe_buffer_ptr);
1703
1704     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1705
1706     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1707     if (FAILED(hr)) {
1708         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1709     }
1710
1711     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1712     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1713     exdata.dwVertexCount = 8;
1714     exdata.dwInstructionOffset = 256;
1715     exdata.dwInstructionLength = exe_length;
1716     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1717     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1718
1719     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1720     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1721
1722     if (SUCCEEDED(hr)) {
1723         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1724         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1725         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1726         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1727     }
1728
1729     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1730     ok(color == 0, "Got color %08x, expected 00000000\n", color);
1731
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 == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1737
1738     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1739     ok(color == 0, "Got color %08x, expected 00000000\n", color);
1740
1741     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1742     red =   (color & 0x00ff0000) >> 16;
1743     green = (color & 0x0000ff00) >>  8;
1744     blue =  (color & 0x000000ff);
1745     ok(red >= 0x7e && red <= 0x82 &&  green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1746
1747     /* 5) Test alpha again, now with color keyed P8 texture */
1748     if(Texture) IDirect3DTexture_Release(Texture);
1749     Texture = NULL;
1750     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1751     TexSurface = NULL;
1752
1753     hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1754                                                 &p8_textures_supported);
1755     ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1756
1757     if (!p8_textures_supported) {
1758         skip("device has no P8 texture support, skipping test\n");
1759     } else {
1760         memset (&ddsd, 0, sizeof (ddsd));
1761         ddsd.dwSize = sizeof (ddsd);
1762         ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1763         ddsd.dwHeight = 128;
1764         ddsd.dwWidth = 128;
1765         ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1766         ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1767         ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1768         U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 8;
1769
1770         hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1771         ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1772         if (FAILED(hr)) {
1773             skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1774             goto out;
1775         }
1776
1777         memset(table1, 0, sizeof(table1));
1778         table1[0].peBlue = 0xff;
1779         table1[1].peRed = 0xff;
1780
1781         hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1782         ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1783         if (FAILED(hr)) {
1784             skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1785             goto out;
1786         }
1787
1788         hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1789         ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1790
1791         hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1792                     (void *)&Texture);
1793         ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1794         if (FAILED(hr)) {
1795             skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1796             goto out;
1797         }
1798
1799         memset(&ddbltfx, 0, sizeof(ddbltfx));
1800         ddbltfx.dwSize = sizeof(ddbltfx);
1801         U5(ddbltfx).dwFillColor = 0;
1802         hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1803         ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1804         U5(ddbltfx).dwFillColor = 0;
1805         hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1806         ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1807         U5(ddbltfx).dwFillColor = 1;
1808         hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1809         ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1810
1811         clrKey.dwColorSpaceLowValue = 1;
1812         clrKey.dwColorSpaceHighValue = 1;
1813         hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1814         ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1815
1816         memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1817         exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1818         hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1819         ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1820         if (FAILED(hr)) {
1821             skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1822             goto out;
1823         }
1824
1825         memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1826
1827         exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1828
1829         EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1830
1831         EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1832         EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1833         hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1834         ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1835         EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1836
1837         EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1838         EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1839
1840         EXEBUF_END(exe_buffer_ptr);
1841
1842         exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1843
1844         hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1845         if (FAILED(hr)) {
1846             trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1847         }
1848
1849         memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1850         exdata.dwSize = sizeof(D3DEXECUTEDATA);
1851         exdata.dwVertexCount = 8;
1852         exdata.dwInstructionOffset = 256;
1853         exdata.dwInstructionLength = exe_length;
1854         hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1855         ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1856
1857         hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1858         ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1859
1860         if (SUCCEEDED(hr)) {
1861             hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1862             ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1863             hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1864             ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1865         }
1866
1867         color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1868         ok(color == 0, "Got color %08x, expected 00000000\n", color);
1869
1870         color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1871         red =   (color & 0x00ff0000) >> 16;
1872         green = (color & 0x0000ff00) >>  8;
1873         blue =  (color & 0x000000ff);
1874         ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1875
1876         color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1877         ok(color == 0, "Got color %08x, expected 00000000\n", color);
1878
1879         color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1880         red =   (color & 0x00ff0000) >> 16;
1881         green = (color & 0x0000ff00) >>  8;
1882         blue =  (color & 0x000000ff);
1883         ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1884     }
1885
1886     out:
1887
1888     if (Palette) IDirectDrawPalette_Release(Palette);
1889     if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1890     if (Texture) IDirect3DTexture_Release(Texture);
1891 }
1892
1893 static void D3D1_ViewportClearTest(void)
1894 {
1895     HRESULT hr;
1896     IDirect3DMaterial *bgMaterial = NULL;
1897     D3DMATERIAL mat;
1898     D3DMATERIALHANDLE hMat;
1899     D3DVIEWPORT vp_data;
1900     IDirect3DViewport *Viewport2 = NULL;
1901     DWORD color, red, green, blue;
1902
1903     hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
1904     ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
1905     if (FAILED(hr)) {
1906         goto out;
1907     }
1908
1909     hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
1910     ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1911     if (FAILED(hr)) {
1912         goto out;
1913     }
1914
1915     hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
1916     ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1917     hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
1918     ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1919     vp_data.dwSize = sizeof(vp_data);
1920     vp_data.dwX = 200;
1921     vp_data.dwY = 200;
1922     vp_data.dwWidth = 100;
1923     vp_data.dwHeight = 100;
1924     vp_data.dvScaleX = 1;
1925     vp_data.dvScaleY = 1;
1926     vp_data.dvMaxX = 100;
1927     vp_data.dvMaxY = 100;
1928     vp_data.dvMinZ = 0;
1929     vp_data.dvMaxZ = 1;
1930     hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
1931     ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1932
1933     memset(&mat, 0, sizeof(mat));
1934     mat.dwSize = sizeof(mat);
1935     U1(U(mat).diffuse).r = 1.0f;
1936     hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
1937     ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
1938
1939     hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
1940     ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
1941
1942     hr = IDirect3DViewport_SetBackground(Viewport, hMat);
1943     ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
1944     hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
1945     ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
1946
1947     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1948     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1949
1950     if (SUCCEEDED(hr)) {
1951         D3DRECT rect;
1952
1953         U1(rect).x1 = U2(rect).y1 = 0;
1954         U3(rect).x2 = 640;
1955         U4(rect).y2 = 480;
1956
1957         hr = IDirect3DViewport_Clear(Viewport,  1,  &rect, D3DCLEAR_TARGET);
1958         ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
1959
1960         memset(&mat, 0, sizeof(mat));
1961         mat.dwSize = sizeof(mat);
1962         U3(U(mat).diffuse).b = 1.0f;
1963         hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
1964         ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
1965
1966         hr = IDirect3DViewport_Clear(Viewport2,  1,  &rect, D3DCLEAR_TARGET);
1967         ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
1968
1969         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1970         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1971         }
1972
1973     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1974     red =   (color & 0x00ff0000) >> 16;
1975     green = (color & 0x0000ff00) >>  8;
1976     blue =  (color & 0x000000ff);
1977     ok((red == 0xff && green == 0 && blue == 0) ||
1978        broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
1979        "Got color %08x, expected 00ff0000\n", color);
1980
1981     color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
1982     red =   (color & 0x00ff0000) >> 16;
1983     green = (color & 0x0000ff00) >>  8;
1984     blue =  (color & 0x000000ff);
1985     ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
1986
1987     out:
1988
1989     if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
1990     if (Viewport2) IDirect3DViewport_Release(Viewport2);
1991 }
1992
1993 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
1994 {
1995     DWORD ret;
1996     HRESULT hr;
1997     DDSURFACEDESC2 ddsd;
1998     RECT rectToLock = {x, y, x+1, y+1};
1999     IDirectDrawSurface4 *surf = NULL;
2000
2001     /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
2002      * to an offscreen surface and lock it instead of the front buffer
2003      */
2004     memset(&ddsd, 0, sizeof(ddsd));
2005     ddsd.dwSize = sizeof(ddsd);
2006     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2007     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
2008     ddsd.dwWidth = 640;
2009     ddsd.dwHeight = 480;
2010     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
2011     hr = IDirectDraw4_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
2012     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2013     if(!surf)
2014     {
2015         trace("cannot create helper surface\n");
2016         return 0xdeadbeef;
2017     }
2018
2019     memset(&ddsd, 0, sizeof(ddsd));
2020     ddsd.dwSize = sizeof(ddsd);
2021     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2022
2023     hr = IDirectDrawSurface4_BltFast(surf, 0, 0, Surface, NULL, 0);
2024     ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
2025     if(FAILED(hr))
2026     {
2027         trace("Cannot blit\n");
2028         ret = 0xdeadbee;
2029         goto out;
2030     }
2031
2032     hr = IDirectDrawSurface4_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
2033     if(FAILED(hr))
2034     {
2035         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
2036         ret = 0xdeadbeec;
2037         goto out;
2038     }
2039
2040     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
2041      * really important for these tests
2042      */
2043     ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
2044     hr = IDirectDrawSurface4_Unlock(surf, NULL);
2045     if(FAILED(hr))
2046     {
2047         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
2048     }
2049
2050 out:
2051     IDirectDrawSurface4_Release(surf);
2052     return ret;
2053 }
2054
2055 static void D3D3_ViewportClearTest(void)
2056 {
2057     HRESULT hr;
2058     IDirectDraw *DirectDraw1 = NULL;
2059     IDirectDraw4 *DirectDraw4 = NULL;
2060     IDirectDrawSurface4 *Primary = NULL;
2061     IDirect3D3 *Direct3D3 = NULL;
2062     IDirect3DViewport3 *Viewport3 = NULL;
2063     IDirect3DViewport3 *SmallViewport3 = NULL;
2064     IDirect3DDevice3 *Direct3DDevice3 = NULL;
2065     WNDCLASS wc = {0};
2066     DDSURFACEDESC2 ddsd;
2067     D3DVIEWPORT2 vp_data;
2068     DWORD color, red, green, blue;
2069     D3DRECT rect;
2070     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
2071                       0.0f, 1.0f, 0.0f, 0.0f,
2072                       0.0f, 0.0f, 1.0f, 0.0f,
2073                       0.0f, 0.0f, 0.0f, 1.0f };
2074     struct vertex quad[] =
2075     {
2076         {-1.0f, -1.0f,   0.1f,                          0xffffffff},
2077         {-1.0f,  1.0f,   0.1f,                          0xffffffff},
2078         { 1.0f,  1.0f,   0.1f,                          0xffffffff},
2079         { 1.0f, -1.0f,   0.1f,                          0xffffffff},
2080     };
2081
2082     WORD Indices[] = {0, 1, 2, 2, 3, 0};
2083     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
2084
2085     wc.lpfnWndProc = DefWindowProc;
2086     wc.lpszClassName = "D3D3_ViewportClearTest_wc";
2087     RegisterClass(&wc);
2088     window = CreateWindow("D3D3_ViewportClearTest_wc", "D3D3_ViewportClearTest",
2089                             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2090
2091     hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2092     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2093     if(FAILED(hr)) goto out;
2094
2095     hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2096     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2097     if(FAILED(hr)) goto out;
2098
2099     hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2100     if(FAILED(hr)) {
2101         /* 24 bit is fine too */
2102         hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2103     }
2104     ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2105     if (FAILED(hr)) goto out;
2106
2107     hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void**)&DirectDraw4);
2108     ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
2109     if(FAILED(hr)) goto out;
2110
2111     memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2112     ddsd.dwSize = sizeof(DDSURFACEDESC2);
2113     ddsd.dwFlags    = DDSD_CAPS;
2114     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
2115
2116     hr = IDirectDraw_CreateSurface(DirectDraw4, &ddsd, &Primary, NULL);
2117     ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2118     if(FAILED(hr)) goto out;
2119
2120     hr = IDirectDraw4_QueryInterface(DirectDraw4, &IID_IDirect3D3, (void**)&Direct3D3);
2121     ok(hr==DD_OK, "IDirectDraw4_QueryInterface returned: %08x\n", hr);
2122     if(FAILED(hr)) goto out;
2123
2124     hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DHALDevice, Primary, &Direct3DDevice3, NULL);
2125     if(FAILED(hr)) {
2126         trace("Creating a HAL device failed, trying Ref\n");
2127         hr = IDirect3D3_CreateDevice(Direct3D3, &IID_IDirect3DRefDevice, Primary, &Direct3DDevice3, NULL);
2128     }
2129     ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
2130     if(FAILED(hr)) goto out;
2131
2132     hr = IDirect3D3_CreateViewport(Direct3D3, &Viewport3, NULL);
2133     ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2134     if(FAILED(hr)) goto out;
2135
2136     hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, Viewport3);
2137     ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2138
2139     memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2140     vp_data.dwSize = sizeof(D3DVIEWPORT2);
2141     vp_data.dwWidth = 640;
2142     vp_data.dwHeight = 480;
2143     vp_data.dvClipX = -1.0f;
2144     vp_data.dvClipWidth = 2.0f;
2145     vp_data.dvClipY = 1.0f;
2146     vp_data.dvClipHeight = 2.0f;
2147     vp_data.dvMaxZ = 1.0f;
2148     hr = IDirect3DViewport3_SetViewport2(Viewport3, &vp_data);
2149     ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2150
2151     hr = IDirect3D3_CreateViewport(Direct3D3, &SmallViewport3, NULL);
2152     ok(hr==DD_OK, "IDirect3D3_CreateViewport returned: %08x\n", hr);
2153     if(FAILED(hr)) goto out;
2154
2155     hr = IDirect3DDevice3_AddViewport(Direct3DDevice3, SmallViewport3);
2156     ok(hr==DD_OK, "IDirect3DDevice3_AddViewport returned: %08x\n", hr);
2157
2158     memset(&vp_data, 0, sizeof(D3DVIEWPORT2));
2159     vp_data.dwSize = sizeof(D3DVIEWPORT2);
2160     vp_data.dwX = 400;
2161     vp_data.dwY = 100;
2162     vp_data.dwWidth = 100;
2163     vp_data.dwHeight = 100;
2164     vp_data.dvClipX = -1.0f;
2165     vp_data.dvClipWidth = 2.0f;
2166     vp_data.dvClipY = 1.0f;
2167     vp_data.dvClipHeight = 2.0f;
2168     vp_data.dvMaxZ = 1.0f;
2169     hr = IDirect3DViewport3_SetViewport2(SmallViewport3, &vp_data);
2170     ok(hr==DD_OK, "IDirect3DViewport3_SetViewport2 returned: %08x\n", hr);
2171
2172     hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2173     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2174
2175     hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
2176     ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2177     hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
2178     ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2179     hr = IDirect3DDevice3_SetTransform(Direct3DDevice3, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
2180     ok(hr == D3D_OK, "IDirect3DDevice3_SetTransform returned %08x\n", hr);
2181     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CLIPPING, FALSE);
2182     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2183     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ZENABLE, FALSE);
2184     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2185     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_FOGENABLE, FALSE);
2186     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2187     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_STENCILENABLE, FALSE);
2188     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2189     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
2190     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2191     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
2192     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2193     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
2194     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState failed with %08x\n", hr);
2195     hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
2196     ok(hr == D3D_OK, "IDirect3DDevice3_SetRenderState returned %08x\n", hr);
2197
2198     if (SUCCEEDED(hr)) {
2199         U1(rect).x1 = U2(rect).y1 = 0;
2200         U3(rect).x2 = 640;
2201         U4(rect).y2 = 480;
2202
2203         hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x00ff00, 0.0f, 0);
2204         ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2205
2206         hr = IDirect3DViewport3_Clear2(SmallViewport3, 1, &rect, D3DCLEAR_TARGET, 0xff0000, 0.0f, 0);
2207         ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2208
2209         hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2210         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2211         }
2212
2213     color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2214     red =   (color & 0x00ff0000) >> 16;
2215     green = (color & 0x0000ff00) >>  8;
2216     blue =  (color & 0x000000ff);
2217     ok(red == 0 && green == 0xff && blue == 0, "Got color %08x, expected 0000ff00\n", color);
2218
2219     color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2220     red =   (color & 0x00ff0000) >> 16;
2221     green = (color & 0x0000ff00) >>  8;
2222     blue =  (color & 0x000000ff);
2223     ok(red == 0xff && green == 0 && blue == 0, "Got color %08x, expected 00ff0000\n", color);
2224
2225     /* Test that clearing viewport doesn't interfere with rendering to previously active viewport. */
2226     hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
2227     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
2228
2229     if (SUCCEEDED(hr)) {
2230         hr = IDirect3DDevice3_SetCurrentViewport(Direct3DDevice3, SmallViewport3);
2231         ok(hr == D3D_OK, "IDirect3DDevice3_SetCurrentViewport failed with %08x\n", hr);
2232
2233         hr = IDirect3DViewport3_Clear2(Viewport3, 1, &rect, D3DCLEAR_TARGET, 0x000000, 0.0f, 0);
2234         ok(hr == D3D_OK, "IDirect3DViewport3_Clear2 failed, hr = %08x\n", hr);
2235
2236         hr = IDirect3DDevice3_DrawIndexedPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf, quad, 4 /* NumVerts */,
2237                                                     Indices, 6 /* Indexcount */, 0 /* flags */);
2238         ok(hr == D3D_OK, "IDirect3DDevice3_DrawIndexedPrimitive failed with %08x\n", hr);
2239
2240         hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
2241         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
2242         }
2243
2244     color = D3D3_getPixelColor(DirectDraw4, Primary, 5, 5);
2245     red =   (color & 0x00ff0000) >> 16;
2246     green = (color & 0x0000ff00) >>  8;
2247     blue =  (color & 0x000000ff);
2248     ok(red == 0 && green == 0 && blue == 0, "Got color %08x, expected 00000000\n", color);
2249
2250     color = D3D3_getPixelColor(DirectDraw4, Primary, 405, 105);
2251     red =   (color & 0x00ff0000) >> 16;
2252     green = (color & 0x0000ff00) >>  8;
2253     blue =  (color & 0x000000ff);
2254     ok(red == 0xff && green == 0xff && blue == 0xff, "Got color %08x, expected 00ffffff\n", color);
2255
2256     out:
2257
2258     if (SmallViewport3) IDirect3DViewport3_Release(SmallViewport3);
2259     if (Viewport3) IDirect3DViewport3_Release(Viewport3);
2260     if (Direct3DDevice3) IDirect3DDevice3_Release(Direct3DDevice3);
2261     if (Direct3D3) IDirect3D3_Release(Direct3D3);
2262     if (Primary) IDirectDrawSurface4_Release(Primary);
2263     if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
2264     if (DirectDraw4) IDirectDraw4_Release(DirectDraw4);
2265     if(window) DestroyWindow(window);
2266 }
2267
2268 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
2269 {
2270     DDSURFACEDESC ddsd;
2271     HRESULT hr;
2272     UINT i, i1;
2273     BYTE *p;
2274
2275     memset(&ddsd, 0, sizeof(ddsd));
2276     ddsd.dwSize = sizeof(ddsd);
2277
2278     hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
2279     ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2280
2281     p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2282
2283     for (i = 0; i < h; i++) {
2284         for (i1 = 0; i1 < w; i1++) {
2285             p[i1] = colorindex;
2286         }
2287         p += U1(ddsd).lPitch;
2288     }
2289
2290     hr = IDirectDrawSurface_Unlock(dest, NULL);
2291     ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2292 }
2293
2294 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
2295 {
2296     COLORREF clr = CLR_INVALID;
2297     HDC hdc;
2298     HRESULT hr;
2299
2300     hr = IDirectDrawSurface_GetDC(Surface, &hdc);
2301     ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2302
2303     if (SUCCEEDED(hr)) {
2304         clr = GetPixel(hdc, x, y);
2305
2306         hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
2307         ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2308     }
2309
2310     return clr;
2311 }
2312
2313 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
2314 {
2315     int i;
2316
2317     for (i = 0; i < 256; i++) {
2318        if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
2319            table1[i].peBlue != table2[i].rgbBlue) return FALSE;
2320     }
2321
2322     return TRUE;
2323 }
2324
2325 static void p8_primary_test(void)
2326 {
2327     /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
2328     DDSURFACEDESC ddsd;
2329     HDC hdc;
2330     HRESULT hr;
2331     PALETTEENTRY entries[256];
2332     RGBQUAD coltable[256];
2333     UINT i, i1, i2;
2334     IDirectDrawPalette *ddprimpal = NULL;
2335     IDirectDrawSurface *offscreen = NULL;
2336     WNDCLASS wc = {0};
2337     DDBLTFX ddbltfx;
2338     COLORREF color;
2339     RECT rect;
2340     DDCOLORKEY clrKey;
2341     unsigned differences;
2342
2343     /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
2344     hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
2345
2346     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2347     if (FAILED(hr)) {
2348         goto out;
2349     }
2350
2351     wc.lpfnWndProc = DefWindowProc;
2352     wc.lpszClassName = "p8_primary_test_wc";
2353     RegisterClass(&wc);
2354     window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2355
2356     hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2357     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2358     if(FAILED(hr)) {
2359         goto out;
2360     }
2361
2362     hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
2363     ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2364     if (FAILED(hr)) {
2365         goto out;
2366     }
2367
2368     memset(&ddsd, 0, sizeof(ddsd));
2369     ddsd.dwSize = sizeof(ddsd);
2370     ddsd.dwFlags = DDSD_CAPS;
2371     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2372     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
2373     ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
2374     if (FAILED(hr)) {
2375         goto out;
2376     }
2377
2378     memset(entries, 0, sizeof(entries));
2379     entries[0].peRed = 0xff;
2380     entries[1].peGreen = 0xff;
2381     entries[2].peBlue = 0xff;
2382
2383     hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
2384     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2385     if (FAILED(hr)) {
2386         skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
2387         goto out;
2388     }
2389
2390     hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
2391     ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2392
2393     p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
2394
2395     color = getPixelColor_GDI(Surface1, 10, 10);
2396     ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
2397             "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2398             GetRValue(color), GetGValue(color), GetBValue(color));
2399
2400     memset(&ddbltfx, 0, sizeof(ddbltfx));
2401     ddbltfx.dwSize = sizeof(ddbltfx);
2402     U5(ddbltfx).dwFillColor = 0;
2403     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2404     ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2405
2406     color = getPixelColor_GDI(Surface1, 10, 10);
2407     ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
2408             "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
2409             GetRValue(color), GetGValue(color), GetBValue(color));
2410
2411     memset(&ddbltfx, 0, sizeof(ddbltfx));
2412     ddbltfx.dwSize = sizeof(ddbltfx);
2413     U5(ddbltfx).dwFillColor = 1;
2414     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2415     ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
2416
2417     color = getPixelColor_GDI(Surface1, 10, 10);
2418     ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2419             "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2420             GetRValue(color), GetGValue(color), GetBValue(color));
2421
2422     memset (&ddsd, 0, sizeof (ddsd));
2423     ddsd.dwSize = sizeof (ddsd);
2424     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2425     ddsd.dwWidth = 16;
2426     ddsd.dwHeight = 16;
2427     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
2428     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2429     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2430     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 8;
2431     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2432     ok(hr == DD_OK ||
2433        broken(hr == DDERR_INVALIDPIXELFORMAT) || /* VMware */
2434        broken(hr == DDERR_NODIRECTDRAWHW), /* VMware */
2435        "IDirectDraw_CreateSurface returned %08x\n", hr);
2436     if (FAILED(hr)) goto out;
2437
2438     memset(entries, 0, sizeof(entries));
2439     for (i = 0; i < 256; i++) {
2440         entries[i].peBlue = i;
2441         }
2442     hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2443     ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2444
2445     hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
2446     ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
2447     i = GetDIBColorTable(hdc, 0, 256, coltable);
2448     ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
2449     hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
2450     ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
2451
2452     ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
2453
2454     p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 2);
2455
2456     memset(entries, 0, sizeof(entries));
2457     entries[0].peRed = 0xff;
2458     entries[1].peGreen = 0xff;
2459     entries[2].peBlue = 0xff;
2460     entries[3].peRed = 0x80;
2461     hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
2462     ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
2463
2464     hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2465     ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2466
2467     color = getPixelColor_GDI(Surface1, 1, 1);
2468     ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2469             "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2470             GetRValue(color), GetGValue(color), GetBValue(color));
2471
2472     /* Color keyed blit. */
2473     p8_surface_fill_rect(offscreen, 0, 0, 8, 8, 3);
2474     clrKey.dwColorSpaceLowValue = 3;
2475     clrKey.dwColorSpaceHighValue = 3;
2476     hr = IDirectDrawSurface_SetColorKey(offscreen, DDCKEY_SRCBLT, &clrKey);
2477     ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
2478
2479     hr = IDirectDrawSurface_BltFast(Surface1, 100, 100, offscreen, NULL, DDBLTFAST_SRCCOLORKEY);
2480     ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2481
2482     color = getPixelColor_GDI(Surface1, 105, 105);
2483     ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2484             "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2485             GetRValue(color), GetGValue(color), GetBValue(color));
2486
2487     color = getPixelColor_GDI(Surface1, 112, 112);
2488     ok(GetRValue(color) == 0 && GetGValue(color) == 0x00 && GetBValue(color) == 0xFF,
2489             "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
2490             GetRValue(color), GetGValue(color), GetBValue(color));
2491
2492     rect.left = 100;
2493     rect.top = 200;
2494     rect.right = 116;
2495     rect.bottom = 216;
2496
2497     memset(&ddbltfx, 0, sizeof(ddbltfx));
2498     ddbltfx.dwSize = sizeof(ddbltfx);
2499     ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 2;
2500     hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2501         DDBLT_WAIT | DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2502     ok(hr==DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned: %x\n", hr);
2503     hr = IDirectDrawSurface_Blt(Surface1, &rect, offscreen, NULL,
2504         DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx);
2505     ok(hr==DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2506
2507     color = getPixelColor_GDI(Surface1, 105, 205);
2508     ok(GetRValue(color) == 0x80 && GetGValue(color) == 0 && GetBValue(color) == 0,
2509             "got R %02X G %02X B %02X, expected R 80 G 00 B 00\n",
2510             GetRValue(color), GetGValue(color), GetBValue(color));
2511
2512     color = getPixelColor_GDI(Surface1, 112, 212);
2513     ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
2514             "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
2515             GetRValue(color), GetGValue(color), GetBValue(color));
2516
2517     /* Test blitting and locking patterns that are likely to trigger bugs in opengl renderer (p8
2518        surface conversion and uploading/downloading to/from opengl texture). Similar patterns (
2519        blitting front buffer areas to/from an offscreen surface mixed with locking) are used by C&C
2520        Red Alert I. */
2521     IDirectDrawSurface_Release(offscreen);
2522
2523     memset (&ddsd, 0, sizeof (ddsd));
2524     ddsd.dwSize = sizeof (ddsd);
2525     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
2526     ddsd.dwWidth = 640;
2527     ddsd.dwHeight = 480;
2528     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2529     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2530     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2531     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 8;
2532     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
2533     ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
2534
2535     if (FAILED(hr)) goto out;
2536
2537     /* Test two times, first time front buffer has a palette and second time front buffer
2538        has no palette; the latter is somewhat contrived example, but an app could set
2539        front buffer palette later. */
2540     for (i2 = 0; i2 < 2; i2++) {
2541         if (i2 == 1) {
2542             hr = IDirectDrawSurface_SetPalette(Surface1, NULL);
2543             ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
2544         }
2545
2546         memset(&ddsd, 0, sizeof(ddsd));
2547         ddsd.dwSize = sizeof(ddsd);
2548         hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2549         ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2550
2551         for (i = 0; i < 256; i++) {
2552             unsigned x = (i % 128) * 4;
2553             unsigned y = (i / 128) * 4;
2554             BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2555
2556             for (i1 = 0; i1 < 4; i1++) {
2557                 p[0] = p[1] = p[2] = p[3] = i;
2558                 p += U1(ddsd).lPitch;
2559             }
2560         }
2561
2562         hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2563         ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2564
2565         hr = IDirectDrawSurface_BltFast(offscreen, 0, 0, Surface1, NULL, 0);
2566         ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2567
2568         /* This ensures offscreen surface contents will be downloaded to system memory. */
2569         memset(&ddsd, 0, sizeof(ddsd));
2570         ddsd.dwSize = sizeof(ddsd);
2571         hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2572         ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2573         hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2574         ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2575
2576         /* Offscreen surface data will have to be converted and uploaded to texture. */
2577         rect.left = 0;
2578         rect.top = 0;
2579         rect.right = 16;
2580         rect.bottom = 16;
2581         hr = IDirectDrawSurface_BltFast(offscreen, 600, 400, Surface1, &rect, 0);
2582         ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2583
2584         /* This ensures offscreen surface contents will be downloaded to system memory. */
2585         memset(&ddsd, 0, sizeof(ddsd));
2586         ddsd.dwSize = sizeof(ddsd);
2587         hr = IDirectDrawSurface_Lock(offscreen, NULL, &ddsd, DDLOCK_WAIT, NULL);
2588         ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2589         hr = IDirectDrawSurface_Unlock(offscreen, NULL);
2590         ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2591
2592         hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
2593         ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
2594
2595         memset(&ddsd, 0, sizeof(ddsd));
2596         ddsd.dwSize = sizeof(ddsd);
2597         hr = IDirectDrawSurface_Lock(Surface1, NULL, &ddsd, DDLOCK_WAIT, NULL);
2598         ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
2599
2600         differences = 0;
2601
2602         for (i = 0; i < 256; i++) {
2603             unsigned x = (i % 128) * 4 + 1;
2604             unsigned y = (i / 128) * 4 + 1;
2605             BYTE *p = (BYTE *)ddsd.lpSurface + U1(ddsd).lPitch * y + x;
2606
2607             if (*p != i) differences++;
2608         }
2609
2610         hr = IDirectDrawSurface_Unlock(Surface1, NULL);
2611         ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
2612
2613         ok(differences == 0, i2 == 0 ? "Pass 1. Unexpected front buffer contents after blit (%u differences)\n" :
2614                 "Pass 2 (with NULL front buffer palette). Unexpected front buffer contents after blit (%u differences)\n",
2615                 differences);
2616     }
2617
2618     out:
2619
2620     if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
2621     if(offscreen) IDirectDrawSurface_Release(offscreen);
2622     if(Surface1) IDirectDrawSurface_Release(Surface1);
2623     if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
2624     if(window) DestroyWindow(window);
2625 }
2626
2627 static void cubemap_test(IDirect3DDevice7 *device)
2628 {
2629     IDirect3D7 *d3d;
2630     IDirectDraw7 *ddraw;
2631     IDirectDrawSurface7 *cubemap, *surface;
2632     D3DDEVICEDESC7 d3dcaps;
2633     HRESULT hr;
2634     DWORD color;
2635     DDSURFACEDESC2 ddsd;
2636     DDBLTFX DDBltFx;
2637     DDSCAPS2 caps;
2638     static float quad[] = {
2639       -1.0,   -1.0,    0.1,    1.0,    0.0,    0.0, /* Lower left */
2640        0.0,   -1.0,    0.1,    1.0,    0.0,    0.0,
2641       -1.0,    0.0,    0.1,    1.0,    0.0,    0.0,
2642        0.0,    0.0,    0.1,    1.0,    0.0,    0.0,
2643
2644        0.0,   -1.0,    0.1,    0.0,    1.0,    0.0, /* Lower right */
2645        1.0,   -1.0,    0.1,    0.0,    1.0,    0.0,
2646        0.0,    0.0,    0.1,    0.0,    1.0,    0.0,
2647        1.0,    0.0,    0.1,    0.0,    1.0,    0.0,
2648
2649        0.0,    0.0,    0.1,    0.0,    0.0,    1.0, /* upper right */
2650        1.0,    0.0,    0.1,    0.0,    0.0,    1.0,
2651        0.0,    1.0,    0.1,    0.0,    0.0,    1.0,
2652        1.0,    1.0,    0.1,    0.0,    0.0,    1.0,
2653
2654       -1.0,    0.0,    0.1,   -1.0,    0.0,    0.0, /* Upper left */
2655        0.0,    0.0,    0.1,   -1.0,    0.0,    0.0,
2656       -1.0,    1.0,    0.1,   -1.0,    0.0,    0.0,
2657        0.0,    1.0,    0.1,   -1.0,    0.0,    0.0,
2658     };
2659
2660     memset(&DDBltFx, 0, sizeof(DDBltFx));
2661     DDBltFx.dwSize = sizeof(DDBltFx);
2662
2663     memset(&d3dcaps, 0, sizeof(d3dcaps));
2664     hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
2665     ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2666     if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2667     {
2668         skip("No cubemap support\n");
2669         return;
2670     }
2671
2672     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2673     ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
2674
2675     hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2676     ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
2677     hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
2678     ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
2679     IDirect3D7_Release(d3d);
2680
2681
2682     memset(&ddsd, 0, sizeof(ddsd));
2683     ddsd.dwSize = sizeof(ddsd);
2684     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2685     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2686     ddsd.dwWidth = 16;
2687     ddsd.dwHeight = 16;
2688     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2689     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
2690     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2691     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2692     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2693     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2694     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2695
2696     hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
2697     ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
2698     IDirectDraw7_Release(ddraw);
2699
2700     /* Positive X */
2701     U5(DDBltFx).dwFillColor = 0x00ff0000;
2702     hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2703     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2704
2705     memset(&caps, 0, sizeof(caps));
2706     caps.dwCaps = DDSCAPS_TEXTURE;
2707     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
2708     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2709     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2710     U5(DDBltFx).dwFillColor = 0x0000ffff;
2711     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2712     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2713
2714     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
2715     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2716     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2717     U5(DDBltFx).dwFillColor = 0x0000ff00;
2718     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2719     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2720
2721     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
2722     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2723     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2724     U5(DDBltFx).dwFillColor = 0x000000ff;
2725     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2726     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2727
2728     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2729     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2730     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2731     U5(DDBltFx).dwFillColor = 0x00ffff00;
2732     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2733     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2734
2735     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2736     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2737     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2738     U5(DDBltFx).dwFillColor = 0x00ff00ff;
2739     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2740     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2741
2742     hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2743     ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2744     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2745     ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2746     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2747     ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2748
2749     hr = IDirect3DDevice7_BeginScene(device);
2750     ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2751     if(SUCCEEDED(hr))
2752     {
2753         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2754         if (hr == DDERR_UNSUPPORTED || hr == DDERR_NODIRECTDRAWHW)
2755         {
2756             /* VMware */
2757             win_skip("IDirect3DDevice7_DrawPrimitive is not completely implemented, colors won't be tested\n");
2758             hr = IDirect3DDevice7_EndScene(device);
2759             ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2760             goto out;
2761         }
2762         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2763         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
2764         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2765         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 8 * 6, 4, 0);
2766         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2767         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 12* 6, 4, 0);
2768         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2769
2770         hr = IDirect3DDevice7_EndScene(device);
2771         ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2772     }
2773     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2774     ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2775
2776     color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2777     ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2778     color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2779     ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2780     color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2781     ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2782     color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2783     ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2784
2785 out:
2786     hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2787     ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2788     IDirectDrawSurface7_Release(cubemap);
2789 }
2790
2791 /* This test tests depth clamping / clipping behaviour:
2792  *   - With software vertex processing, depth values are clamped to the
2793  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
2794  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
2795  *     same as regular vertices here.
2796  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
2797  *     Normal vertices are always clipped. Pretransformed vertices are
2798  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
2799  *   - The viewport's MinZ/MaxZ is irrelevant for this.
2800  */
2801 static void depth_clamp_test(IDirect3DDevice7 *device)
2802 {
2803     struct tvertex quad1[] =
2804     {
2805         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
2806         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
2807         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
2808         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
2809     };
2810     struct tvertex quad2[] =
2811     {
2812         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2813         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
2814         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2815         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
2816     };
2817     struct tvertex quad3[] =
2818     {
2819         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
2820         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
2821         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
2822         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
2823     };
2824     struct tvertex quad4[] =
2825     {
2826         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
2827         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
2828         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2829         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
2830     };
2831     struct vertex quad5[] =
2832     {
2833         { -0.5f,   0.5f, 10.0f,       0xff14f914},
2834         {  0.5f,   0.5f, 10.0f,       0xff14f914},
2835         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
2836         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
2837     };
2838     struct vertex quad6[] =
2839     {
2840         { -1.0f,   0.5f, 10.0f,       0xfff91414},
2841         {  1.0f,   0.5f, 10.0f,       0xfff91414},
2842         { -1.0f,  0.25f, 10.0f,       0xfff91414},
2843         {  1.0f,  0.25f, 10.0f,       0xfff91414},
2844     };
2845
2846     D3DVIEWPORT7 vp;
2847     D3DCOLOR color;
2848     HRESULT hr;
2849
2850     vp.dwX = 0;
2851     vp.dwY = 0;
2852     vp.dwWidth = 640;
2853     vp.dwHeight = 480;
2854     vp.dvMinZ = 0.0;
2855     vp.dvMaxZ = 7.5;
2856
2857     hr = IDirect3DDevice7_SetViewport(device, &vp);
2858     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2859
2860     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
2861     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2862
2863     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
2864     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2865     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
2866     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2867     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZWRITEENABLE, TRUE);
2868     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2869     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
2870     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2871
2872     hr = IDirect3DDevice7_BeginScene(device);
2873     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2874
2875     hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
2876     ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2877     hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad2, 4, 0);
2878     ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2879
2880     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
2881     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2882
2883     hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad3, 4, 0);
2884     ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2885     hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad4, 4, 0);
2886     ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2887
2888     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
2889     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2890
2891     hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad5, 4, 0);
2892     ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2893
2894     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, TRUE);
2895     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2896
2897     hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad6, 4, 0);
2898     ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2899
2900     hr = IDirect3DDevice7_EndScene(device);
2901     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2902
2903     color = getPixelColor(device, 75, 75);
2904     ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2905     color = getPixelColor(device, 150, 150);
2906     ok(color_match(color, 0x00ffffff, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2907     color = getPixelColor(device, 320, 240);
2908     ok(color_match(color, 0x00002b7f, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2909     color = getPixelColor(device, 320, 330);
2910     ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2911     color = getPixelColor(device, 320, 330);
2912     ok(color_match(color, 0x00f9e814, 1) || color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
2913
2914     vp.dvMinZ = 0.0;
2915     vp.dvMaxZ = 1.0;
2916     hr = IDirect3DDevice7_SetViewport(device, &vp);
2917     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
2918 }
2919
2920 static void DX1_BackBufferFlipTest(void)
2921 {
2922     HRESULT hr;
2923     IDirectDraw *DirectDraw1 = NULL;
2924     IDirectDrawSurface *Primary = NULL;
2925     IDirectDrawSurface *Backbuffer = NULL;
2926     WNDCLASS wc = {0};
2927     DDSURFACEDESC ddsd;
2928     DDBLTFX ddbltfx;
2929     COLORREF color;
2930     const DWORD white = 0xffffff;
2931     const DWORD red = 0xff0000;
2932     BOOL attached = FALSE;
2933
2934     wc.lpfnWndProc = DefWindowProc;
2935     wc.lpszClassName = "DX1_BackBufferFlipTest_wc";
2936     RegisterClass(&wc);
2937     window = CreateWindow("DX1_BackBufferFlipTest_wc", "DX1_BackBufferFlipTest",
2938                             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2939
2940     hr = DirectDrawCreate( NULL, &DirectDraw1, NULL );
2941     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
2942     if(FAILED(hr)) goto out;
2943
2944     hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2945     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
2946     if(FAILED(hr)) goto out;
2947
2948     hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
2949     if(FAILED(hr)) {
2950         /* 24 bit is fine too */
2951         hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
2952     }
2953     ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
2954     if (FAILED(hr)) {
2955         goto out;
2956     }
2957
2958     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
2959     ddsd.dwSize = sizeof(DDSURFACEDESC);
2960     ddsd.dwFlags = DDSD_CAPS;
2961     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2962
2963     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Primary, NULL);
2964     ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2965
2966     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
2967     ddsd.dwSize = sizeof(DDSURFACEDESC);
2968     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2969     ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2970     ddsd.dwWidth = 640;
2971     ddsd.dwHeight = 480;
2972     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2973     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2974     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
2975     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
2976     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
2977     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
2978
2979     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Backbuffer, NULL);
2980     ok(hr==DD_OK, "IDirectDraw_CreateSurface returned: %08x\n", hr);
2981     if(FAILED(hr)) goto out;
2982
2983     hr = IDirectDrawSurface_AddAttachedSurface(Primary, Backbuffer);
2984     todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2985        "Attaching a back buffer to a front buffer returned %08x\n", hr);
2986     if (FAILED(hr)) goto out;
2987
2988     attached = TRUE;
2989
2990     memset(&ddbltfx, 0, sizeof(ddbltfx));
2991     ddbltfx.dwSize = sizeof(ddbltfx);
2992     U5(ddbltfx).dwFillColor = red;
2993     hr = IDirectDrawSurface_Blt(Backbuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2994     ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2995
2996     U5(ddbltfx).dwFillColor = white;
2997     hr = IDirectDrawSurface_Blt(Primary, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2998     ok(hr == DD_OK, "IDirectDrawSurface_Blt returned: %x\n", hr);
2999
3000     /* Check it out */
3001     color = getPixelColor_GDI(Primary, 5, 5);
3002     ok(GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF,
3003             "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3004             GetRValue(color), GetGValue(color), GetBValue(color));
3005
3006     color = getPixelColor_GDI(Backbuffer, 5, 5);
3007     ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3008             "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3009             GetRValue(color), GetGValue(color), GetBValue(color));
3010
3011     hr = IDirectDrawSurface_Flip(Primary, NULL, DDFLIP_WAIT);
3012     todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3013
3014     if (hr == DD_OK)
3015     {
3016         color = getPixelColor_GDI(Primary, 5, 5);
3017         ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
3018                 "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
3019                 GetRValue(color), GetGValue(color), GetBValue(color));
3020
3021         color = getPixelColor_GDI(Backbuffer, 5, 5);
3022         ok((GetRValue(color) == 0xFF && GetGValue(color) == 0xFF && GetBValue(color) == 0xFF) ||
3023            broken(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0),  /* broken driver */
3024                 "got R %02X G %02X B %02X, expected R FF G FF B FF\n",
3025                 GetRValue(color), GetGValue(color), GetBValue(color));
3026     }
3027
3028     out:
3029
3030     if (Backbuffer)
3031     {
3032         if (attached)
3033             IDirectDrawSurface_DeleteAttachedSurface(Primary, 0, Backbuffer);
3034         IDirectDrawSurface_Release(Backbuffer);
3035     }
3036     if (Primary) IDirectDrawSurface_Release(Primary);
3037     if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
3038     if (window) DestroyWindow(window);
3039 }
3040
3041 START_TEST(visual)
3042 {
3043     HRESULT hr;
3044     DWORD color;
3045     if(!createObjects())
3046     {
3047         skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
3048         return;
3049     }
3050
3051     /* Check for the reliability of the returned data */
3052     hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3053     if(FAILED(hr))
3054     {
3055         skip("Clear failed, can't assure correctness of the test results, skipping\n");
3056         goto cleanup;
3057     }
3058
3059     color = getPixelColor(Direct3DDevice, 1, 1);
3060     if(color !=0x00ff0000)
3061     {
3062         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3063         goto cleanup;
3064     }
3065
3066     hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
3067     if(FAILED(hr))
3068     {
3069         skip("Clear failed, can't assure correctness of the test results, skipping\n");
3070         goto cleanup;
3071     }
3072
3073     color = getPixelColor(Direct3DDevice, 639, 479);
3074     if(color != 0x0000ddee)
3075     {
3076         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
3077         goto cleanup;
3078     }
3079
3080     /* Now run the tests */
3081     blt_test(Direct3DDevice);
3082     depth_clamp_test(Direct3DDevice);
3083     lighting_test(Direct3DDevice);
3084     clear_test(Direct3DDevice);
3085     fog_test(Direct3DDevice);
3086     offscreen_test(Direct3DDevice);
3087     alpha_test(Direct3DDevice);
3088     rhw_zero_test(Direct3DDevice);
3089     cubemap_test(Direct3DDevice);
3090
3091     releaseObjects(); /* release DX7 interfaces to test D3D1 */
3092
3093     if(!D3D1_createObjects()) {
3094         skip("Cannot initialize D3D1, skipping\n");
3095     }
3096     else {
3097         D3D1_TextureMapBlendTest();
3098         D3D1_ViewportClearTest();
3099     }
3100     D3D1_releaseObjects();
3101
3102     D3D3_ViewportClearTest();
3103     p8_primary_test();
3104     DX1_BackBufferFlipTest();
3105
3106     return ;
3107
3108 cleanup:
3109     releaseObjects();
3110 }