ddraw: Add a D3D7 cube map test.
[wine] / dlls / ddraw / tests / visual.c
1 /*
2  * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
20
21 #include <assert.h>
22 #include "wine/test.h"
23 #include "ddraw.h"
24 #include "d3d.h"
25
26 HWND window;
27 IDirectDraw7        *DirectDraw = NULL;
28 IDirectDrawSurface7 *Surface;
29 IDirect3D7          *Direct3D = NULL;
30 IDirect3DDevice7    *Direct3DDevice = NULL;
31
32 IDirectDraw *DirectDraw1 = NULL;
33 IDirectDrawSurface *Surface1 = NULL;
34 IDirect3D *Direct3D1 = NULL;
35 IDirect3DDevice *Direct3DDevice1 = NULL;
36 IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
37 IDirect3DViewport *Viewport = NULL;
38
39 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
40
41 static BOOL createObjects(void)
42 {
43     HRESULT hr;
44     HMODULE hmod = GetModuleHandleA("ddraw.dll");
45     WNDCLASS wc = {0};
46     DDSURFACEDESC2 ddsd;
47
48
49     if(!hmod) return FALSE;
50     pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
51     if(!pDirectDrawCreateEx) return FALSE;
52
53     hr = pDirectDrawCreateEx(NULL, (void **) &DirectDraw, &IID_IDirectDraw7, NULL);
54     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
55     if(!DirectDraw) goto err;
56
57     wc.lpfnWndProc = &DefWindowProc;
58     wc.lpszClassName = "d3d7_test_wc";
59     RegisterClass(&wc);
60     window = CreateWindow("d3d7_test_wc", "d3d7_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
61
62     hr = IDirectDraw7_SetCooperativeLevel(DirectDraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
63     ok(hr == DD_OK, "IDirectDraw7_SetCooperativeLevel failed with %08x\n", hr);
64     if(FAILED(hr)) goto err;
65     hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 32, 0, 0);
66     if(FAILED(hr)) {
67         /* 24 bit is fine too */
68         hr = IDirectDraw7_SetDisplayMode(DirectDraw, 640, 480, 24, 0, 0);
69
70     }
71     ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "IDirectDraw7_SetDisplayMode failed with %08x\n", hr);
72     if(FAILED(hr)) {
73         /* use trace, the caller calls skip() */
74         trace("SetDisplayMode failed\n");
75         goto err;
76     }
77
78     hr = IDirectDraw7_QueryInterface(DirectDraw, &IID_IDirect3D7, (void**) &Direct3D);
79     if (hr == E_NOINTERFACE) goto err;
80     ok(hr==DD_OK, "QueryInterface returned: %08x\n", hr);
81
82     /* DirectDraw Flipping behavior doesn't seem that well-defined. The reference rasterizer behaves differently
83      * than hardware implementations. Request single buffering, that seems to work everywhere
84      */
85     memset(&ddsd, 0, sizeof(ddsd));
86     ddsd.dwSize = sizeof(ddsd);
87     ddsd.dwFlags = DDSD_CAPS;
88     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
89     ddsd.dwBackBufferCount = 1;
90     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &Surface, NULL);
91     ok(hr==DD_OK, "CreateSurface returned: %08x\n", hr);
92     if(!Surface) goto err;
93
94     hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DTnLHalDevice, Surface, &Direct3DDevice);
95     if(FAILED(hr))
96     {
97         trace("Creating a TnLHal Device failed, trying HAL\n");
98         hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DHALDevice, Surface, &Direct3DDevice);
99         if(FAILED(hr))
100         {
101             trace("Creating a HAL device failed, trying Ref\n");
102             hr = IDirect3D7_CreateDevice(Direct3D, &IID_IDirect3DRefDevice, Surface, &Direct3DDevice);
103         }
104     }
105     ok(hr == D3D_OK, "IDirect3D7_CreateDevice failed with %08x\n", hr);
106     if(!Direct3DDevice) goto err;
107     return TRUE;
108
109     err:
110     if(DirectDraw) IDirectDraw7_Release(DirectDraw);
111     if(Surface) IDirectDrawSurface7_Release(Surface);
112     if(Direct3D) IDirect3D7_Release(Direct3D);
113     if(Direct3DDevice) IDirect3DDevice7_Release(Direct3DDevice);
114     if(window) DestroyWindow(window);
115     return FALSE;
116 }
117
118 static void releaseObjects(void)
119 {
120     IDirect3DDevice7_Release(Direct3DDevice);
121     IDirect3D7_Release(Direct3D);
122     IDirectDrawSurface7_Release(Surface);
123     IDirectDraw7_Release(DirectDraw);
124     DestroyWindow(window);
125 }
126
127 static DWORD getPixelColor(IDirect3DDevice7 *device, UINT x, UINT y)
128 {
129     DWORD ret;
130     HRESULT hr;
131     DDSURFACEDESC2 ddsd;
132     RECT rectToLock = {x, y, x+1, y+1};
133     IDirectDrawSurface7 *surf = NULL;
134
135     /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
136      * to an offscreen surface and lock it instead of the front buffer
137      */
138     memset(&ddsd, 0, sizeof(ddsd));
139     ddsd.dwSize = sizeof(ddsd);
140     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
141     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
142     ddsd.dwWidth = 640;
143     ddsd.dwHeight = 480;
144     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
145     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &surf, NULL);
146     ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with %08x\n", hr);
147     if(!surf)
148     {
149         trace("cannot create helper surface\n");
150         return 0xdeadbeef;
151     }
152
153     memset(&ddsd, 0, sizeof(ddsd));
154     ddsd.dwSize = sizeof(ddsd);
155     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
156
157     hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
158     ok(hr == DD_OK, "IDirectDrawSurface7_BltFast returned %08x\n", hr);
159     if(FAILED(hr))
160     {
161         trace("Cannot blit\n");
162         ret = 0xdeadbee;
163         goto out;
164     }
165
166     hr = IDirectDrawSurface7_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
167     if(FAILED(hr))
168     {
169         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
170         ret = 0xdeadbeec;
171         goto out;
172     }
173
174     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
175      * really important for these tests
176      */
177     ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
178     hr = IDirectDrawSurface7_Unlock(surf, &rectToLock);
179     if(FAILED(hr))
180     {
181         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
182     }
183
184 out:
185     IDirectDrawSurface7_Release(surf);
186     return ret;
187 }
188
189 struct vertex
190 {
191     float x, y, z;
192     DWORD diffuse;
193 };
194
195 struct nvertex
196 {
197     float x, y, z;
198     float nx, ny, nz;
199     DWORD diffuse;
200 };
201
202 static void lighting_test(IDirect3DDevice7 *device)
203 {
204     HRESULT hr;
205     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
206     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
207     DWORD color;
208
209     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
210                       0.0f, 1.0f, 0.0f, 0.0f,
211                       0.0f, 0.0f, 1.0f, 0.0f,
212                       0.0f, 0.0f, 0.0f, 1.0f };
213
214     struct vertex unlitquad[] =
215     {
216         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
217         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
218         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
219         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
220     };
221     struct vertex litquad[] =
222     {
223         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
224         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
225         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
226         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
227     };
228     struct nvertex unlitnquad[] =
229     {
230         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
231         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
232         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
233         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
234     };
235     struct nvertex litnquad[] =
236     {
237         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
238         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
239         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
240         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
241     };
242     WORD Indices[] = {0, 1, 2, 2, 3, 0};
243
244     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
245     ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
246
247     /* Setup some states that may cause issues */
248     hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX *) mat);
249     ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
250     hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX *)mat);
251     ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
252     hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX *) mat);
253     ok(hr == D3D_OK, "IDirect3DDevice7_SetTransform returned %08x\n", hr);
254     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
255     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
256     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
257     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
258     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
259     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
260     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_STENCILENABLE, FALSE);
261     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
262     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
263     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
264     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
265     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
266     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
267     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed with %08x\n", hr);
268
269     hr = IDirect3DDevice7_BeginScene(device);
270     ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
271     if(hr == D3D_OK)
272     {
273         /* No lights are defined... That means, lit vertices should be entirely black */
274         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
275         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
276         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, unlitquad, 4 /* NumVerts */,
277                                                     Indices, 6 /* Indexcount */, 0 /* flags */);
278         ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
279
280         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
281         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
282         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, litquad, 4 /* NumVerts */,
283                                                     Indices, 6 /* Indexcount */, 0 /* flags */);
284         ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
285
286         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
287         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
288         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, unlitnquad, 4 /* NumVerts */,
289                                                     Indices, 6 /* Indexcount */, 0 /* flags */);
290         ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
291
292         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
293         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
294         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, litnquad, 4 /* NumVerts */,
295                                                     Indices, 6 /* Indexcount */, 0 /* flags */);
296         ok(hr == D3D_OK, "IDirect3DDevice7_DrawIndexedPrimitiveUP failed with %08x\n", hr);
297
298         IDirect3DDevice7_EndScene(device);
299         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
300     }
301
302     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
303     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
304     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
305     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
306     color = getPixelColor(device, 480, 360); /* lower left quad - unlit width normals */
307     ok(color == 0x000000ff, "Unlit quad width normals has color %08x\n", color);
308     color = getPixelColor(device, 480, 120); /* upper left quad - lit width normals */
309     ok(color == 0x00000000, "Lit quad width normals has color %08x\n", color);
310
311     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
312     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
313 }
314
315 static void clear_test(IDirect3DDevice7 *device)
316 {
317     /* Tests the correctness of clearing parameters */
318     HRESULT hr;
319     D3DRECT rect[2];
320     D3DRECT rect_negneg;
321     DWORD color;
322
323     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
324     ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
325
326     /* Positive x, negative y */
327     U1(rect[0]).x1 = 0;
328     U2(rect[0]).y1 = 480;
329     U3(rect[0]).x2 = 320;
330     U4(rect[0]).y2 = 240;
331
332     /* Positive x, positive y */
333     U1(rect[1]).x1 = 0;
334     U2(rect[1]).y1 = 0;
335     U3(rect[1]).x2 = 320;
336     U4(rect[1]).y2 = 240;
337     /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
338      * is ignored, the positive is still cleared afterwards
339      */
340     hr = IDirect3DDevice7_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
341     ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
342
343     /* negative x, negative y */
344     U1(rect_negneg).x1 = 640;
345     U2(rect_negneg).y1 = 240;
346     U3(rect_negneg).x2 = 320;
347     U4(rect_negneg).y2 = 0;
348     hr = IDirect3DDevice7_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
349     ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
350
351     color = getPixelColor(device, 160, 360); /* lower left quad */
352     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
353     color = getPixelColor(device, 160, 120); /* upper left quad */
354     ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
355     color = getPixelColor(device, 480, 360); /* lower right quad  */
356     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
357     color = getPixelColor(device, 480, 120); /* upper right quad */
358     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
359 }
360
361 struct sVertex {
362     float x, y, z;
363     DWORD diffuse;
364     DWORD specular;
365 };
366
367 struct sVertexT {
368     float x, y, z, rhw;
369     DWORD diffuse;
370     DWORD specular;
371 };
372
373 static void fog_test(IDirect3DDevice7 *device)
374 {
375     HRESULT hr;
376     DWORD color;
377     float start = 0.0, end = 1.0;
378     D3DDEVICEDESC7 caps;
379
380     /* Gets full z based fog with linear fog, no fog with specular color */
381     struct sVertex unstransformed_1[] = {
382         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
383         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
384         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
385         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
386     };
387     /* Ok, I am too lazy to deal with transform matrices */
388     struct sVertex unstransformed_2[] = {
389         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
390         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
391         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
392         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
393     };
394     /* Untransformed ones. Give them a different diffuse color to make the test look
395      * nicer. It also makes making sure that they are drawn correctly easier.
396      */
397     struct sVertexT transformed_1[] = {
398         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
399         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
400         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
401         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
402     };
403     struct sVertexT transformed_2[] = {
404         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
405         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
406         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
407         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
408     };
409     WORD Indices[] = {0, 1, 2, 2, 3, 0};
410
411     memset(&caps, 0, sizeof(caps));
412     hr = IDirect3DDevice7_GetCaps(device, &caps);
413     ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
414     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
415     ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr);
416
417     /* Setup initial states: No lighting, fog on, fog color */
418     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
419     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
420     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE);
421     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
422     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */);
423     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
424
425     /* First test: Both table fog and vertex fog off */
426     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE);
427     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
428     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
429     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
430
431     /* Start = 0, end = 1. Should be default, but set them */
432     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start));
433     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
434     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end));
435     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
436
437     if(IDirect3DDevice7_BeginScene(device) == D3D_OK)
438     {
439         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
440         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
441                                                    unstransformed_1, 4, Indices, 6, 0);
442         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
443
444         /* That makes it use the Z value */
445         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR);
446         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
447         /* Untransformed, vertex fog != none (or table fog != none):
448          * Use the Z value as input into the equation
449          */
450         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
451                                                    unstransformed_2, 4, Indices, 6, 0);
452         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
453
454         /* transformed verts */
455         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
456         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
457         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
458                                                    transformed_1, 4, Indices, 6, 0);
459         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
460
461         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
462         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
463         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
464          * equation
465          */
466         hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
467                                                    transformed_2, 4, Indices, 6, 0);
468         ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr);
469
470         hr = IDirect3DDevice7_EndScene(device);
471         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
472     }
473     else
474     {
475         ok(FALSE, "BeginScene failed\n");
476     }
477
478     color = getPixelColor(device, 160, 360);
479     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
480     color = getPixelColor(device, 160, 120);
481     ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
482     color = getPixelColor(device, 480, 120);
483     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
484     if(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
485     {
486         color = getPixelColor(device, 480, 360);
487         ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
488     }
489     else
490     {
491         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
492          * The settings above result in no fogging with vertex fog
493          */
494         color = getPixelColor(device, 480, 120);
495         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
496         trace("Info: Table fog not supported by this device\n");
497     }
498
499     /* Turn off the fog master switch to avoid confusing other tests */
500     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
501     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
502 }
503
504 static void offscreen_test(IDirect3DDevice7 *device)
505 {
506     HRESULT hr;
507     IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
508     DWORD color;
509     DDSURFACEDESC2 ddsd;
510
511     static const float quad[][5] = {
512         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
513         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
514         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
515         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
516     };
517
518     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
519     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
520
521     memset(&ddsd, 0, sizeof(ddsd));
522     ddsd.dwSize = sizeof(ddsd);
523     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
524     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
525     ddsd.dwWidth = 128;
526     ddsd.dwHeight = 128;
527     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
528     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
529     ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
530     if(!offscreen) {
531         goto out;
532     }
533
534     hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
535     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
536     if(!backbuffer) {
537         goto out;
538     }
539
540     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
541     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
542     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
543     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
544     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
545     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
546     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
547     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
548     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
549     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned hr = %08x\n", hr);
550
551     if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
552         hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
553         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
554         hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
555         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
556
557         /* Draw without textures - Should resut in a white quad */
558         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
559         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
560
561         hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
562         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
563         hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
564         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
565
566         /* This time with the texture */
567         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, quad, 4, 0);
568         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
569
570         IDirect3DDevice7_EndScene(device);
571     }
572
573     /* Center quad - should be white */
574     color = getPixelColor(device, 320, 240);
575     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
576     /* Some quad in the cleared part of the texture */
577     color = getPixelColor(device, 170, 240);
578     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
579     /* Part of the originally cleared back buffer */
580     color = getPixelColor(device, 10, 10);
581     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
582     if(0) {
583         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
584          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
585          * the offscreen rendering mode this test would succeed or fail
586          */
587         color = getPixelColor(device, 10, 470);
588         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
589     }
590
591 out:
592     hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
593
594     /* restore things */
595     if(backbuffer) {
596         hr = IDirect3DDevice7_SetRenderTarget(device, backbuffer, 0);
597         IDirectDrawSurface7_Release(backbuffer);
598     }
599     if(offscreen) {
600         IDirectDrawSurface7_Release(offscreen);
601     }
602 }
603
604 static void alpha_test(IDirect3DDevice7 *device)
605 {
606     HRESULT hr;
607     IDirectDrawSurface7 *backbuffer = NULL, *offscreen = NULL;
608     DWORD color, red, green, blue;
609     DDSURFACEDESC2 ddsd;
610
611     struct vertex quad1[] =
612     {
613         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
614         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
615         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
616         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
617     };
618     struct vertex quad2[] =
619     {
620         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
621         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
622         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
623         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
624     };
625     static const float composite_quad[][5] = {
626         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
627         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
628         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
629         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
630     };
631
632     /* Clear the render target with alpha = 0.5 */
633     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
634     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
635
636     memset(&ddsd, 0, sizeof(ddsd));
637     ddsd.dwSize = sizeof(ddsd);
638     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
639     ddsd.dwWidth = 128;
640     ddsd.dwHeight = 128;
641     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
642     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
643     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount      = 32;
644     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
645     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
646     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask         = 0x000000ff;
647     U5(U4(ddsd).ddpfPixelFormat).dwRGBAlphaBitMask  = 0xff000000;
648     hr = IDirectDraw7_CreateSurface(DirectDraw, &ddsd, &offscreen, NULL);
649     ok(hr == D3D_OK, "Creating the offscreen render target failed, hr = %08x\n", hr);
650     if(!offscreen) {
651         goto out;
652     }
653     hr = IDirect3DDevice7_GetRenderTarget(device, &backbuffer);
654     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
655     if(!backbuffer) {
656         goto out;
657     }
658
659     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
660     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
661     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
662     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
663     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DFILTER_NEAREST);
664     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
665     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DFILTER_NEAREST);
666     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
667
668     hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
669     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
670     if(IDirect3DDevice7_BeginScene(device) == D3D_OK) {
671
672         /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
673          * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
674          * the input alpha
675          *
676          * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
677          * They give essentially ZERO and ONE blend factors
678          */
679         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
680         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
681         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
682         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
683         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
684         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
685
686         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
687         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
688         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
689         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
690         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 4, 0);
691         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
692
693         /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
694          * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
695          * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
696          * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
697          * vertices
698          */
699         hr = IDirect3DDevice7_SetRenderTarget(device, offscreen, 0);
700         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
701         hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
702         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
703
704         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
705         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
706         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
707         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
708         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0);
709         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
710
711         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTALPHA);
712         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
713         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVDESTALPHA);
714         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
715         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad2, 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, "Can't get back buffer, hr = %08x\n", hr);
720
721         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
722          * Disable alpha blending for the final composition
723          */
724         hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
725         ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState failed, hr = %08x\n", hr);
726
727         hr = IDirect3DDevice7_SetTexture(device, 0, offscreen);
728         ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
729         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEX1, composite_quad, 4, 0);
730         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
731         hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
732         ok(hr == D3D_OK, "IDirect3DDevice7_SetTexture failed, hr = %08x\n", hr);
733
734         hr = IDirect3DDevice7_EndScene(device);
735         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
736     }
737
738     color = getPixelColor(device, 160, 360);
739     red =   (color & 0x00ff0000) >> 16;
740     green = (color & 0x0000ff00) >>  8;
741     blue =  (color & 0x000000ff);
742     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
743        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
744
745     color = getPixelColor(device, 160, 120);
746     red =   (color & 0x00ff0000) >> 16;
747     green = (color & 0x0000ff00) >>  8;
748     blue =  (color & 0x000000ff);
749     ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
750        "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
751
752     color = getPixelColor(device, 480, 360);
753     red =   (color & 0x00ff0000) >> 16;
754     green = (color & 0x0000ff00) >>  8;
755     blue =  (color & 0x000000ff);
756     ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
757        "SRCALPHA on texture returned color %08x, expected bar\n", color);
758
759     color = getPixelColor(device, 480, 120);
760     red =   (color & 0x00ff0000) >> 16;
761     green = (color & 0x0000ff00) >>  8;
762     blue =  (color & 0x000000ff);
763     ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
764        "DSTALPHA on texture returned color %08x, expected foo\n", color);
765
766     out:
767     if(offscreen) IDirectDrawSurface7_Release(offscreen);
768     if(backbuffer) IDirectDrawSurface7_Release(backbuffer);
769 }
770
771 static void rhw_zero_test(IDirect3DDevice7 *device)
772 {
773 /* Test if it will render a quad correctly when vertex rhw = 0 */
774     HRESULT hr;
775     DWORD color;
776
777     struct {
778         float x, y, z;
779         float rhw;
780         DWORD diffuse;
781         } quad1[] =
782     {
783         {0, 100, 0, 0, 0xffffffff},
784         {0, 0, 0, 0, 0xffffffff},
785         {100, 100, 0, 0, 0xffffffff},
786         {100, 0, 0, 0, 0xffffffff},
787     };
788
789     /* Clear to black */
790     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0, 0);
791     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
792
793     hr = IDirect3DDevice7_BeginScene(device);
794     ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
795
796     if (SUCCEEDED(hr)) {
797         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, quad1, 4, 0);
798         ok(hr == D3D_OK, "DrawPrimitive failed, hr = %08x\n", hr);
799
800         hr = IDirect3DDevice7_EndScene(device);
801         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
802     }
803
804     color = getPixelColor(device, 5, 5);
805     ok(color == 0xffffff, "Got color %08x, expected 00ffffff\n", color);
806
807     color = getPixelColor(device, 105, 105);
808     ok(color == 0, "Got color %08x, expected 00000000\n", color);
809 }
810
811 static BOOL D3D1_createObjects(void)
812 {
813     WNDCLASS wc = {0};
814     HRESULT hr;
815     DDSURFACEDESC ddsd;
816     D3DEXECUTEBUFFERDESC exdesc;
817     D3DVIEWPORT vp_data;
818
819     /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
820     hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
821
822     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
823     if (FAILED(hr)) {
824         return FALSE;
825     }
826
827     wc.lpfnWndProc = &DefWindowProc;
828     wc.lpszClassName = "texturemapblend_test_wc";
829     RegisterClass(&wc);
830     window = CreateWindow("texturemapblend_test_wc", "texturemapblend_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
831
832     hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
833     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
834     if(FAILED(hr)) {
835         return FALSE;
836     }
837
838     hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
839     if(FAILED(hr)) {
840         /* 24 bit is fine too */
841         hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
842     }
843     ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
844     if (FAILED(hr)) {
845         return FALSE;
846     }
847
848     hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
849     ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
850     if (FAILED(hr)) {
851         return FALSE;
852     }
853
854     memset(&ddsd, 0, sizeof(ddsd));
855     ddsd.dwSize = sizeof(ddsd);
856     ddsd.dwFlags = DDSD_CAPS;
857     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
858     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
859     ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
860     if (FAILED(hr)) {
861         return FALSE;
862     }
863
864     hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
865     if(FAILED(hr)) {
866         trace("Creating a HAL device failed, trying Ref\n");
867         hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
868     }
869     ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
870     if(FAILED(hr)) {
871         return FALSE;
872     }
873
874     hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
875     ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
876     if (FAILED(hr)) {
877         return FALSE;
878     }
879
880     hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
881     ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
882     hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
883     ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
884     vp_data.dwSize = sizeof(vp_data);
885     vp_data.dwX = 0;
886     vp_data.dwY = 0;
887     vp_data.dwWidth = 640;
888     vp_data.dwHeight = 480;
889     vp_data.dvScaleX = 1;
890     vp_data.dvScaleY = 1;
891     vp_data.dvMaxX = 640;
892     vp_data.dvMaxY = 480;
893     vp_data.dvMinZ = 0;
894     vp_data.dvMaxZ = 1;
895     hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
896     ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
897
898     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
899     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
900     exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
901     exdesc.dwBufferSize = 512;
902     exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
903     hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
904     ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
905     if (FAILED(hr)) {
906         return FALSE;
907     }
908
909     return TRUE;
910 }
911
912 static void D3D1_releaseObjects(void)
913 {
914     if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
915     if(Surface1) IDirectDrawSurface_Release(Surface1);
916     if(Viewport) IDirect3DViewport_Release(Viewport);
917     if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
918     if(Direct3D1) IDirect3D_Release(Direct3D1);
919     if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
920     if(window) DestroyWindow(window);
921 }
922
923 static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
924 {
925     DWORD ret;
926     HRESULT hr;
927     DDSURFACEDESC ddsd;
928     RECT rectToLock = {x, y, x+1, y+1};
929     IDirectDrawSurface *surf = NULL;
930
931     /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
932      * to an offscreen surface and lock it instead of the front buffer
933      */
934     memset(&ddsd, 0, sizeof(ddsd));
935     ddsd.dwSize = sizeof(ddsd);
936     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
937     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
938     ddsd.dwWidth = 640;
939     ddsd.dwHeight = 480;
940     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
941     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
942     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
943     if(!surf)
944     {
945         trace("cannot create helper surface\n");
946         return 0xdeadbeef;
947     }
948
949     memset(&ddsd, 0, sizeof(ddsd));
950     ddsd.dwSize = sizeof(ddsd);
951     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
952
953     hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
954     ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
955     if(FAILED(hr))
956     {
957         trace("Cannot blit\n");
958         ret = 0xdeadbee;
959         goto out;
960     }
961
962     hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
963     if(FAILED(hr))
964     {
965         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
966         ret = 0xdeadbeec;
967         goto out;
968     }
969
970     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
971      * really important for these tests
972      */
973     ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
974     hr = IDirectDrawSurface_Unlock(surf, &rectToLock);
975     if(FAILED(hr))
976     {
977         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
978     }
979
980 out:
981     IDirectDrawSurface_Release(surf);
982     return ret;
983 }
984
985 #define EXEBUF_START_RENDER_STATES(count, ptr) do {\
986                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_STATERENDER;\
987                          ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DSTATE);\
988                          ((D3DINSTRUCTION*)(ptr))->wCount = count;\
989                          ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
990
991 #define EXEBUF_PUT_RENDER_STATE(state, value, ptr) do {\
992                          U1(*((D3DSTATE*)(ptr))).drstRenderStateType = state; \
993                          U2(*((D3DSTATE*)(ptr))).dwArg[0] = value; \
994                          ptr = ((D3DSTATE*)(ptr))+1; } while (0)
995
996 #define EXEBUF_PUT_PROCESSVERTICES(nvertices, ptr) do {\
997                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_PROCESSVERTICES;\
998                          ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DPROCESSVERTICES);\
999                          ((D3DINSTRUCTION*)(ptr))->wCount = 1;\
1000                          ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1001                          ((D3DPROCESSVERTICES*)(ptr))->dwFlags = D3DPROCESSVERTICES_COPY;\
1002                          ((D3DPROCESSVERTICES*)(ptr))->wStart = 0;\
1003                          ((D3DPROCESSVERTICES*)(ptr))->wDest = 0;\
1004                          ((D3DPROCESSVERTICES*)(ptr))->dwCount = nvertices;\
1005                          ((D3DPROCESSVERTICES*)(ptr))->dwReserved = 0;\
1006                          ptr = ((D3DPROCESSVERTICES*)(ptr))+1; } while (0)
1007
1008 #define EXEBUF_END(ptr) do {\
1009                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_EXIT;\
1010                          ((D3DINSTRUCTION*)(ptr))->bSize = 0;\
1011                          ((D3DINSTRUCTION*)(ptr))->wCount = 0;\
1012                          ptr = ((D3DINSTRUCTION*)(ptr))+1; } while (0)
1013
1014 #define EXEBUF_PUT_QUAD(base_idx, ptr) do {\
1015                          ((D3DINSTRUCTION*)(ptr))->bOpcode = D3DOP_TRIANGLE;\
1016                          ((D3DINSTRUCTION*)(ptr))->bSize = sizeof(D3DTRIANGLE);\
1017                          ((D3DINSTRUCTION*)(ptr))->wCount = 2;\
1018                          ptr = ((D3DINSTRUCTION*)(ptr))+1;\
1019                          U1(*((D3DTRIANGLE*)(ptr))).v1 = base_idx;\
1020                          U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 1; \
1021                          U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1022                          ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1023                          ptr = ((D3DTRIANGLE*)ptr)+1;\
1024                          U1(*((D3DTRIANGLE*)(ptr))).v1 = (base_idx) + 1; \
1025                          U2(*((D3DTRIANGLE*)(ptr))).v2 = (base_idx) + 2; \
1026                          U3(*((D3DTRIANGLE*)(ptr))).v3 = (base_idx) + 3; \
1027                          ((D3DTRIANGLE*)(ptr))->wFlags = 0;\
1028                          ptr = ((D3DTRIANGLE*)(ptr))+1;\
1029                         } while (0)
1030
1031 HRESULT CALLBACK TextureFormatEnumCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext)
1032 {
1033     if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1034         *(BOOL*)lpContext = TRUE;
1035     }
1036
1037     return DDENUMRET_OK;
1038 }
1039
1040 static void D3D1_TextureMapBlendTest(void)
1041 {
1042     HRESULT hr;
1043     DDSURFACEDESC ddsd;
1044     D3DEXECUTEBUFFERDESC exdesc;
1045     D3DEXECUTEDATA exdata;
1046     DDBLTFX ddbltfx;
1047     RECT rect = { 0, 0, 64, 128 };
1048     DWORD color, red, blue, green;
1049     void *exe_buffer_ptr;
1050     DWORD exe_length;
1051     D3DTEXTUREHANDLE htex;
1052     DDCOLORKEY clrKey;
1053     IDirectDrawSurface *TexSurface = NULL;
1054     IDirect3DTexture *Texture = NULL;
1055     IDirectDrawPalette *Palette = NULL;
1056     PALETTEENTRY table1[256];
1057     BOOL p8_textures_supported = FALSE;
1058
1059     struct {
1060         float x, y, z;
1061         float rhw;
1062         DWORD diffuse;
1063         DWORD specular;
1064         float tu, tv;
1065         } test1_quads[] =
1066     {
1067           {0.0f,   0.0f,     0.0f, 1.0f, 0xffffffff, 0, 0.0f, 0.0f},
1068           {640.0f, 0.0f,     0.0f, 1.0f, 0xffffffff, 0, 1.0f, 0.0f},
1069           {640.0f, 240.0f,   0.0f, 1.0f, 0xffffffff, 0, 1.0f, 1.0f},
1070           {0.0f,   240.0f,   0.0f, 1.0f, 0xffffffff, 0, 0.0f, 1.0f},
1071           {0.0f,   240.0f,   0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 0.0f},
1072           {640.0f, 240.0f,   0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 0.0f},
1073           {640.0f, 480.0f,   0.0f, 1.0f, 0x80ffffff, 0, 1.0f, 1.0f},
1074           {0.0f,   480.0f,   0.0f, 1.0f, 0x80ffffff, 0, 0.0f, 1.0f}
1075     },  test2_quads[] =
1076           {
1077           {0.0f,   0.0f,     0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 0.0f},
1078           {640.0f, 0.0f,     0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 0.0f},
1079           {640.0f, 240.0f,   0.0f, 1.0f, 0x00ff0080, 0, 1.0f, 1.0f},
1080           {0.0f,   240.0f,   0.0f, 1.0f, 0x00ff0080, 0, 0.0f, 1.0f},
1081           {0.0f,   240.0f,   0.0f, 1.0f, 0x008000ff, 0, 0.0f, 0.0f},
1082           {640.0f, 240.0f,   0.0f, 1.0f, 0x008000ff, 0, 1.0f, 0.0f},
1083           {640.0f, 480.0f,   0.0f, 1.0f, 0x008000ff, 0, 1.0f, 1.0f},
1084           {0.0f,   480.0f,   0.0f, 1.0f, 0x008000ff, 0, 0.0f, 1.0f}
1085     };
1086
1087     /* 1) Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel*/
1088     memset (&ddsd, 0, sizeof (ddsd));
1089     ddsd.dwSize = sizeof (ddsd);
1090     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1091     ddsd.dwHeight = 128;
1092     ddsd.dwWidth = 128;
1093     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1094     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1095     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1096     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
1097     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
1098     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
1099     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
1100     U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask  = 0xff000000;
1101     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1102     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1103     if (FAILED(hr)) {
1104         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1105         goto out;
1106     }
1107
1108     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1109                 (void *)&Texture);
1110     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1111     if (FAILED(hr)) {
1112         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1113         goto out;
1114     }
1115
1116     memset(&ddbltfx, 0, sizeof(ddbltfx));
1117     ddbltfx.dwSize = sizeof(ddbltfx);
1118     U5(ddbltfx).dwFillColor = 0;
1119     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1120     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1121
1122     U5(ddbltfx).dwFillColor = 0xff0000ff;
1123     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1124     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1125     U5(ddbltfx).dwFillColor = 0x800000ff;
1126     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1127     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1128
1129     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1130     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1131     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1132     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1133     if (FAILED(hr)) {
1134         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1135         goto out;
1136     }
1137
1138     memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1139
1140     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1141
1142     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1143
1144     EXEBUF_START_RENDER_STATES(12, exe_buffer_ptr);
1145     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_CULLMODE,         D3DCULL_NONE,              exe_buffer_ptr);
1146     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ZENABLE,          FALSE,                     exe_buffer_ptr);
1147     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FOGENABLE,        FALSE,                     exe_buffer_ptr);
1148     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SPECULARENABLE,   FALSE,                     exe_buffer_ptr);
1149     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAG,       D3DFILTER_NEAREST,         exe_buffer_ptr);
1150     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMIN,       D3DFILTER_NEAREST,         exe_buffer_ptr);
1151     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_FILLMODE  ,       D3DFILL_SOLID,             exe_buffer_ptr);
1152     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_SRCBLEND,         D3DBLEND_SRCALPHA,         exe_buffer_ptr);
1153     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_DESTBLEND,        D3DBLEND_INVSRCALPHA,      exe_buffer_ptr);
1154     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE,                      exe_buffer_ptr);
1155     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREMAPBLEND,  D3DTBLEND_MODULATE,        exe_buffer_ptr);
1156     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1157     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1158     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1159
1160     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1161     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1162
1163     EXEBUF_END(exe_buffer_ptr);
1164
1165     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1166
1167     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1168     if (FAILED(hr)) {
1169         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1170     }
1171
1172     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1173     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1174     exdata.dwVertexCount = 8;
1175     exdata.dwInstructionOffset = 256;
1176     exdata.dwInstructionLength = exe_length;
1177     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1178     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1179
1180     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1181     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1182
1183     if (SUCCEEDED(hr)) {
1184         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1185         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1186         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1187         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1188     }
1189
1190     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1191     red =   (color & 0x00ff0000) >> 16;
1192     green = (color & 0x0000ff00) >>  8;
1193     blue =  (color & 0x000000ff);
1194     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1195
1196     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1197     red =   (color & 0x00ff0000) >> 16;
1198     green = (color & 0x0000ff00) >>  8;
1199     blue =  (color & 0x000000ff);
1200     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1201
1202     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1203     red =   (color & 0x00ff0000) >> 16;
1204     green = (color & 0x0000ff00) >>  8;
1205     blue =  (color & 0x000000ff);
1206     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1207
1208     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1209     red =   (color & 0x00ff0000) >> 16;
1210     green = (color & 0x0000ff00) >>  8;
1211     blue =  (color & 0x000000ff);
1212     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1213
1214     /* 2) Test alpha with texture that has no alpha channel - alpha should be taken from diffuse color */
1215     if(Texture) IDirect3DTexture_Release(Texture);
1216     Texture = NULL;
1217     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1218     TexSurface = NULL;
1219
1220     memset (&ddsd, 0, sizeof (ddsd));
1221     ddsd.dwSize = sizeof (ddsd);
1222     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1223     ddsd.dwHeight = 128;
1224     ddsd.dwWidth = 128;
1225     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1226     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1227     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1228     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
1229     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
1230     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
1231     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
1232
1233     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1234     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1235     if (FAILED(hr)) {
1236         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1237         goto out;
1238     }
1239
1240     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1241                 (void *)&Texture);
1242     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1243     if (FAILED(hr)) {
1244         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1245         goto out;
1246     }
1247
1248     memset(&ddbltfx, 0, sizeof(ddbltfx));
1249     ddbltfx.dwSize = sizeof(ddbltfx);
1250     U5(ddbltfx).dwFillColor = 0;
1251     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1252     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1253
1254     U5(ddbltfx).dwFillColor = 0xff0000ff;
1255     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1256     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1257     U5(ddbltfx).dwFillColor = 0x800000ff;
1258     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1259     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1260
1261     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1262     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1263     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1264     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1265     if (FAILED(hr)) {
1266         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1267         goto out;
1268     }
1269
1270     memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1271
1272     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1273
1274     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1275
1276     EXEBUF_START_RENDER_STATES(1, exe_buffer_ptr);
1277     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1278     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1279     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1280
1281     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1282     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1283
1284     EXEBUF_END(exe_buffer_ptr);
1285
1286     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1287
1288     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1289     if (FAILED(hr)) {
1290         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1291     }
1292
1293     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1294     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1295     exdata.dwVertexCount = 8;
1296     exdata.dwInstructionOffset = 256;
1297     exdata.dwInstructionLength = exe_length;
1298     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1299     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1300
1301     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1302     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1303
1304     if (SUCCEEDED(hr)) {
1305         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1306         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1307         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1308         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1309     }
1310
1311     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1312     red =   (color & 0x00ff0000) >> 16;
1313     green = (color & 0x0000ff00) >>  8;
1314     blue =  (color & 0x000000ff);
1315     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1316
1317     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1318     red =   (color & 0x00ff0000) >> 16;
1319     green = (color & 0x0000ff00) >>  8;
1320     blue =  (color & 0x000000ff);
1321     ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1322
1323     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1324     red =   (color & 0x00ff0000) >> 16;
1325     green = (color & 0x0000ff00) >>  8;
1326     blue =  (color & 0x000000ff);
1327     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1328
1329     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1330     red =   (color & 0x00ff0000) >> 16;
1331     green = (color & 0x0000ff00) >>  8;
1332     blue =  (color & 0x000000ff);
1333     ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1334
1335     /* 3) Test RGB - should multiply color components from diffuse color and texture */
1336     if(Texture) IDirect3DTexture_Release(Texture);
1337     Texture = NULL;
1338     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1339     TexSurface = NULL;
1340
1341     memset (&ddsd, 0, sizeof (ddsd));
1342     ddsd.dwSize = sizeof (ddsd);
1343     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1344     ddsd.dwHeight = 128;
1345     ddsd.dwWidth = 128;
1346     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1347     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1348     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1349     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 32;
1350     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0x00ff0000;
1351     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x0000ff00;
1352     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x000000ff;
1353     U5(ddsd.ddpfPixelFormat).dwRGBAlphaBitMask  = 0xff000000;
1354     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1355     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1356     if (FAILED(hr)) {
1357         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1358         goto out;
1359     }
1360
1361     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1362                 (void *)&Texture);
1363     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1364     if (FAILED(hr)) {
1365         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1366         goto out;
1367     }
1368
1369     memset(&ddbltfx, 0, sizeof(ddbltfx));
1370     ddbltfx.dwSize = sizeof(ddbltfx);
1371     U5(ddbltfx).dwFillColor = 0;
1372     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1373     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1374
1375     U5(ddbltfx).dwFillColor = 0x00ffffff;
1376     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1377     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1378     U5(ddbltfx).dwFillColor = 0x00ffff80;
1379     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1380     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1381
1382     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1383     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1384     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1385     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1386     if (FAILED(hr)) {
1387         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1388         goto out;
1389     }
1390
1391     memcpy(exdesc.lpData, test2_quads, sizeof(test2_quads));
1392
1393     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1394
1395     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1396
1397     EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1398     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, exe_buffer_ptr);
1399     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1400     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1401     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1402
1403     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1404     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1405
1406     EXEBUF_END(exe_buffer_ptr);
1407
1408     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1409
1410     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1411     if (FAILED(hr)) {
1412         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1413     }
1414
1415     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1416     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1417     exdata.dwVertexCount = 8;
1418     exdata.dwInstructionOffset = 256;
1419     exdata.dwInstructionLength = exe_length;
1420     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1421     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1422
1423     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1424     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1425
1426     if (SUCCEEDED(hr)) {
1427         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1428         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1429         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1430         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1431     }
1432
1433     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1434     red =   (color & 0x00ff0000) >> 16;
1435     green = (color & 0x0000ff00) >>  8;
1436     blue =  (color & 0x000000ff);
1437     ok(red == 0xff &&  green == 0 && blue >= 0x3e && blue <= 0x42, "Got color %08x, expected 00ff0040 or near\n", color);
1438
1439     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1440     red =   (color & 0x00ff0000) >> 16;
1441     green = (color & 0x0000ff00) >>  8;
1442     blue =  (color & 0x000000ff);
1443     ok(red == 0xff &&  green == 0 && blue == 0x80, "Got color %08x, expected 00ff0080 or near\n", color);
1444
1445     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1446     red =   (color & 0x00ff0000) >> 16;
1447     green = (color & 0x0000ff00) >>  8;
1448     blue =  (color & 0x000000ff);
1449     ok(red >= 0x7e && red <= 0x82 &&  green == 0 && blue == 0x80, "Got color %08x, expected 00800080 or near\n", color);
1450
1451     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1452     red =   (color & 0x00ff0000) >> 16;
1453     green = (color & 0x0000ff00) >>  8;
1454     blue =  (color & 0x000000ff);
1455     ok(red >= 0x7e && red <= 0x82 &&  green == 0 && blue == 0xff, "Got color %08x, expected 008000ff or near\n", color);
1456
1457     /* 4) Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere) */
1458     if(Texture) IDirect3DTexture_Release(Texture);
1459     Texture = NULL;
1460     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1461     TexSurface = NULL;
1462
1463     memset (&ddsd, 0, sizeof (ddsd));
1464     ddsd.dwSize = sizeof (ddsd);
1465     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1466     ddsd.dwHeight = 128;
1467     ddsd.dwWidth = 128;
1468     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1469     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1470     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1471     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 16;
1472     U2(ddsd.ddpfPixelFormat).dwRBitMask         = 0xf800;
1473     U3(ddsd.ddpfPixelFormat).dwGBitMask         = 0x07e0;
1474     U4(ddsd.ddpfPixelFormat).dwBBitMask         = 0x001f;
1475
1476     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1477     ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1478     if (FAILED(hr)) {
1479         skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1480         goto out;
1481     }
1482
1483     hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1484                 (void *)&Texture);
1485     ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1486     if (FAILED(hr)) {
1487         skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1488         goto out;
1489     }
1490
1491     memset(&ddbltfx, 0, sizeof(ddbltfx));
1492     ddbltfx.dwSize = sizeof(ddbltfx);
1493     U5(ddbltfx).dwFillColor = 0;
1494     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1495     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1496     U5(ddbltfx).dwFillColor = 0xf800;
1497     hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1498     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1499     U5(ddbltfx).dwFillColor = 0x001f;
1500     hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1501     ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1502
1503     clrKey.dwColorSpaceLowValue = 0x001f;
1504     clrKey.dwColorSpaceHighValue = 0x001f;
1505     hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1506     ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1507
1508     memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1509     exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1510     hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1511     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1512     if (FAILED(hr)) {
1513         skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1514         goto out;
1515     }
1516
1517     memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1518
1519     exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1520
1521     EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1522
1523     EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1524     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1525     hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1526     ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1527     EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1528
1529     EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1530     EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1531
1532     EXEBUF_END(exe_buffer_ptr);
1533
1534     exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1535
1536     hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1537     if (FAILED(hr)) {
1538         trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1539     }
1540
1541     memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1542     exdata.dwSize = sizeof(D3DEXECUTEDATA);
1543     exdata.dwVertexCount = 8;
1544     exdata.dwInstructionOffset = 256;
1545     exdata.dwInstructionLength = exe_length;
1546     hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1547     ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1548
1549     hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1550     ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1551
1552     if (SUCCEEDED(hr)) {
1553         hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1554         ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1555         hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1556         ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1557     }
1558
1559     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1560     ok(color == 0, "Got color %08x, expected 00000000\n", color);
1561
1562     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1563     red =   (color & 0x00ff0000) >> 16;
1564     green = (color & 0x0000ff00) >>  8;
1565     blue =  (color & 0x000000ff);
1566     ok(red == 0xff &&  green == 0 && blue == 0, "Got color %08x, expected 00ff0000 or near\n", color);
1567
1568     color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1569     ok(color == 0, "Got color %08x, expected 00000000\n", color);
1570
1571     color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1572     red =   (color & 0x00ff0000) >> 16;
1573     green = (color & 0x0000ff00) >>  8;
1574     blue =  (color & 0x000000ff);
1575     ok(red >= 0x7e && red <= 0x82 &&  green == 0 && blue == 0, "Got color %08x, expected 00800000 or near\n", color);
1576
1577     /* 5) Test alpha again, now with color keyed P8 texture */
1578     if(Texture) IDirect3DTexture_Release(Texture);
1579     Texture = NULL;
1580     if(TexSurface) IDirectDrawSurface_Release(TexSurface);
1581     TexSurface = NULL;
1582
1583     hr = IDirect3DDevice_EnumTextureFormats(Direct3DDevice1, TextureFormatEnumCallback,
1584                                                 &p8_textures_supported);
1585     ok(hr == DD_OK, "IDirect3DDevice_EnumTextureFormats returned %08x\n", hr);
1586
1587     if (!p8_textures_supported) {
1588         skip("device has no P8 texture support, skipping test\n");
1589     } else {
1590         memset (&ddsd, 0, sizeof (ddsd));
1591         ddsd.dwSize = sizeof (ddsd);
1592         ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1593         ddsd.dwHeight = 128;
1594         ddsd.dwWidth = 128;
1595         ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1596         ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1597         ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1598         U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 8;
1599
1600         hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1601         ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1602         if (FAILED(hr)) {
1603             skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1604             goto out;
1605         }
1606
1607         memset(table1, 0, sizeof(table1));
1608         table1[0].peBlue = 0xff;
1609         table1[1].peRed = 0xff;
1610
1611         hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &Palette, NULL);
1612         ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1613         if (FAILED(hr)) {
1614             skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1615             goto out;
1616         }
1617
1618         hr = IDirectDrawSurface_SetPalette(TexSurface, Palette);
1619         ok(hr==D3D_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1620
1621         hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1622                     (void *)&Texture);
1623         ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1624         if (FAILED(hr)) {
1625             skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1626             goto out;
1627         }
1628
1629         memset(&ddbltfx, 0, sizeof(ddbltfx));
1630         ddbltfx.dwSize = sizeof(ddbltfx);
1631         U5(ddbltfx).dwFillColor = 0;
1632         hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1633         ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1634         U5(ddbltfx).dwFillColor = 0;
1635         hr = IDirectDrawSurface_Blt(TexSurface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1636         ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1637         U5(ddbltfx).dwFillColor = 1;
1638         hr = IDirectDrawSurface_Blt(TexSurface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1639         ok(hr == D3D_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1640
1641         clrKey.dwColorSpaceLowValue = 1;
1642         clrKey.dwColorSpaceHighValue = 1;
1643         hr = IDirectDrawSurface_SetColorKey(TexSurface, DDCKEY_SRCBLT, &clrKey);
1644         ok(hr==D3D_OK, "IDirectDrawSurfac_SetColorKey returned: %x\n", hr);
1645
1646         memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
1647         exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
1648         hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &exdesc);
1649         ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed with %08x\n", hr);
1650         if (FAILED(hr)) {
1651             skip("IDirect3DExecuteBuffer_Lock failed; skipping further tests\n");
1652             goto out;
1653         }
1654
1655         memcpy(exdesc.lpData, test1_quads, sizeof(test1_quads));
1656
1657         exe_buffer_ptr = 256 + (char*)exdesc.lpData;
1658
1659         EXEBUF_PUT_PROCESSVERTICES(8, exe_buffer_ptr);
1660
1661         EXEBUF_START_RENDER_STATES(2, exe_buffer_ptr);
1662         EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE, exe_buffer_ptr);
1663         hr = IDirect3DTexture_GetHandle(Texture, Direct3DDevice1, &htex);
1664         ok(hr == D3D_OK, "IDirect3DTexture_GetHandle failed with %08x\n", hr);
1665         EXEBUF_PUT_RENDER_STATE(D3DRENDERSTATE_TEXTUREHANDLE,  htex, exe_buffer_ptr);
1666
1667         EXEBUF_PUT_QUAD(0, exe_buffer_ptr);
1668         EXEBUF_PUT_QUAD(4, exe_buffer_ptr);
1669
1670         EXEBUF_END(exe_buffer_ptr);
1671
1672         exe_length = ((char*)exe_buffer_ptr - (char*)exdesc.lpData) - 256;
1673
1674         hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1675         if (FAILED(hr)) {
1676             trace("IDirect3DExecuteBuffer_Unlock failed with %08x\n", hr);
1677         }
1678
1679         memset(&exdata, 0, sizeof(D3DEXECUTEDATA));
1680         exdata.dwSize = sizeof(D3DEXECUTEDATA);
1681         exdata.dwVertexCount = 8;
1682         exdata.dwInstructionOffset = 256;
1683         exdata.dwInstructionLength = exe_length;
1684         hr = IDirect3DExecuteBuffer_SetExecuteData(ExecuteBuffer, &exdata);
1685         ok(hr == D3D_OK, "IDirect3DExecuteBuffer_SetExecuteData failed with %08x\n", hr);
1686
1687         hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
1688         ok(hr == D3D_OK, "IDirect3DDevice3_BeginScene failed with %08x\n", hr);
1689
1690         if (SUCCEEDED(hr)) {
1691             hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_UNCLIPPED);
1692             ok(hr == D3D_OK, "IDirect3DDevice_Execute failed, hr = %08x\n", hr);
1693             hr = IDirect3DDevice_EndScene(Direct3DDevice1);
1694             ok(hr == D3D_OK, "IDirect3DDevice3_EndScene failed, hr = %08x\n", hr);
1695         }
1696
1697         color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
1698         ok(color == 0, "Got color %08x, expected 00000000\n", color);
1699
1700         color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 5);
1701         red =   (color & 0x00ff0000) >> 16;
1702         green = (color & 0x0000ff00) >>  8;
1703         blue =  (color & 0x000000ff);
1704         ok(red == 0 &&  green == 0 && blue == 0xff, "Got color %08x, expected 000000ff or near\n", color);
1705
1706         color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 245);
1707         ok(color == 0, "Got color %08x, expected 00000000\n", color);
1708
1709         color = D3D1_getPixelColor(DirectDraw1, Surface1, 400, 245);
1710         red =   (color & 0x00ff0000) >> 16;
1711         green = (color & 0x0000ff00) >>  8;
1712         blue =  (color & 0x000000ff);
1713         ok(red == 0 &&  green == 0 && blue >= 0x7e && blue <= 0x82, "Got color %08x, expected 00000080 or near\n", color);
1714     }
1715
1716     out:
1717
1718     if (Palette) IDirectDrawPalette_Release(Palette);
1719     if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1720     if (Texture) IDirect3DTexture_Release(Texture);
1721 }
1722
1723 static void p8_surface_fill_rect(IDirectDrawSurface *dest, UINT x, UINT y, UINT w, UINT h, BYTE colorindex)
1724 {
1725     DDSURFACEDESC ddsd;
1726     HRESULT hr;
1727     UINT i, i1;
1728     BYTE *p;
1729
1730     memset(&ddsd, 0, sizeof(ddsd));
1731     ddsd.dwSize = sizeof(ddsd);
1732
1733     hr = IDirectDrawSurface_Lock(dest, NULL, &ddsd, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
1734     ok(hr==DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr);
1735
1736     p = (BYTE *)ddsd.lpSurface + ddsd.lPitch * y;
1737
1738     for (i = 0; i < h; i++) {
1739         for (i1 = 0; i1 < w; i1++) {
1740             p[i1] = colorindex;
1741         }
1742         p += ddsd.lPitch;
1743     }
1744
1745     hr = IDirectDrawSurface_Unlock(dest, NULL);
1746     ok(hr==DD_OK, "IDirectDrawSurface_UnLock returned: %x\n", hr);
1747 }
1748
1749 static COLORREF getPixelColor_GDI(IDirectDrawSurface *Surface, UINT x, UINT y)
1750 {
1751     COLORREF clr = CLR_INVALID;
1752     HDC hdc;
1753     HRESULT hr;
1754
1755     hr = IDirectDrawSurface_GetDC(Surface, &hdc);
1756     ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
1757
1758     if (SUCCEEDED(hr)) {
1759         clr = GetPixel(hdc, x, y);
1760
1761         hr = IDirectDrawSurface_ReleaseDC(Surface, hdc);
1762         ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
1763     }
1764
1765     return clr;
1766 }
1767
1768 static BOOL colortables_check_equality(PALETTEENTRY table1[256], RGBQUAD table2[256])
1769 {
1770     int i;
1771
1772     for (i = 0; i < 256; i++) {
1773        if (table1[i].peRed != table2[i].rgbRed || table1[i].peGreen != table2[i].rgbGreen ||
1774            table1[i].peBlue != table2[i].rgbBlue) return FALSE;
1775     }
1776
1777     return TRUE;
1778 }
1779
1780 static void p8_primary_test()
1781 {
1782     /* Test 8bit mode used by games like StarCraft, C&C Red Alert I etc */
1783     DDSURFACEDESC ddsd;
1784     HDC hdc;
1785     HRESULT hr;
1786     PALETTEENTRY entries[256];
1787     RGBQUAD coltable[256];
1788     UINT i;
1789     IDirectDrawPalette *ddprimpal = NULL;
1790     IDirectDrawSurface *offscreen = NULL;
1791     WNDCLASS wc = {0};
1792     DDBLTFX ddbltfx;
1793     COLORREF color;
1794
1795     /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1796     hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1797
1798     ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1799     if (FAILED(hr)) {
1800         goto out;
1801     }
1802
1803     wc.lpfnWndProc = &DefWindowProc;
1804     wc.lpszClassName = "p8_primary_test_wc";
1805     RegisterClass(&wc);
1806     window = CreateWindow("p8_primary_test_wc", "p8_primary_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1807
1808     hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1809     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1810     if(FAILED(hr)) {
1811         goto out;
1812     }
1813
1814     hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 8);
1815     ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
1816     if (FAILED(hr)) {
1817         goto out;
1818     }
1819
1820     memset(&ddsd, 0, sizeof(ddsd));
1821     ddsd.dwSize = sizeof(ddsd);
1822     ddsd.dwFlags = DDSD_CAPS;
1823     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1824     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1825     ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
1826     if (FAILED(hr)) {
1827         goto out;
1828     }
1829
1830     memset(entries, 0, sizeof(entries));
1831     entries[0].peRed = 0xff;
1832     entries[1].peGreen = 0xff;
1833     entries[2].peBlue = 0xff;
1834
1835     hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &ddprimpal, NULL);
1836     ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1837     if (FAILED(hr)) {
1838         skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1839         goto out;
1840     }
1841
1842     hr = IDirectDrawSurface_SetPalette(Surface1, ddprimpal);
1843     ok(hr==DD_OK, "IDirectDrawSurface_SetPalette returned: %x\n", hr);
1844
1845     p8_surface_fill_rect(Surface1, 0, 0, 640, 480, 2);
1846
1847     color = getPixelColor_GDI(Surface1, 10, 10);
1848     ok(GetRValue(color) == 0 && GetGValue(color) == 0 && GetBValue(color) == 0xFF,
1849             "got R %02X G %02X B %02X, expected R 00 G 00 B FF\n",
1850             GetRValue(color), GetGValue(color), GetBValue(color));
1851
1852     memset(&ddbltfx, 0, sizeof(ddbltfx));
1853     ddbltfx.dwSize = sizeof(ddbltfx);
1854     U5(ddbltfx).dwFillColor = 0;
1855     hr = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1856     ok(hr == DD_OK, "IDirectDrawSurface_Blt failed with %08x\n", hr);
1857
1858     color = getPixelColor_GDI(Surface1, 10, 10);
1859     ok(GetRValue(color) == 0xFF && GetGValue(color) == 0 && GetBValue(color) == 0,
1860             "got R %02X G %02X B %02X, expected R FF G 00 B 00\n",
1861             GetRValue(color), GetGValue(color), GetBValue(color));
1862
1863     memset (&ddsd, 0, sizeof (ddsd));
1864     ddsd.dwSize = sizeof (ddsd);
1865     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1866     ddsd.dwWidth = 16;
1867     ddsd.dwHeight = 16;
1868     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
1869     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1870     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1871     U1(ddsd.ddpfPixelFormat).dwRGBBitCount      = 8;
1872     hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &offscreen, NULL);
1873     ok(hr == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", hr);
1874     if (FAILED(hr)) goto out;
1875
1876     memset(entries, 0, sizeof(entries));
1877     for (i = 0; i < 256; i++) {
1878         entries[i].peBlue = i;
1879         }
1880     hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
1881     ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
1882
1883     hr = IDirectDrawSurface_GetDC(offscreen, &hdc);
1884     ok(hr==DD_OK, "IDirectDrawSurface_GetDC returned: %x\n", hr);
1885     i = GetDIBColorTable(hdc, 0, 256, coltable);
1886     ok(i == 256, "GetDIBColorTable returned %u, last error: %x\n", i, GetLastError());
1887     hr = IDirectDrawSurface_ReleaseDC(offscreen, hdc);
1888     ok(hr==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %x\n", hr);
1889
1890     ok(colortables_check_equality(entries, coltable), "unexpected colortable on offscreen surface\n");
1891
1892     p8_surface_fill_rect(offscreen, 0, 0, 16, 16, 1);
1893
1894     memset(entries, 0, sizeof(entries));
1895     entries[0].peRed = 0xff;
1896     entries[1].peGreen = 0xff;
1897     entries[2].peBlue = 0xff;
1898     hr = IDirectDrawPalette_SetEntries(ddprimpal, 0, 0, 256, entries);
1899     ok(hr == DD_OK, "IDirectDrawPalette_SetEntries failed with %08x\n", hr);
1900
1901     hr = IDirectDrawSurface_BltFast(Surface1, 0, 0, offscreen, NULL, 0);
1902     ok(hr==DD_OK, "IDirectDrawSurface_BltFast returned: %x\n", hr);
1903
1904     color = getPixelColor_GDI(Surface1, 1, 1);
1905     ok(GetRValue(color) == 0 && GetGValue(color) == 0xFF && GetBValue(color) == 0,
1906             "got R %02X G %02X B %02X, expected R 00 G FF B 00\n",
1907             GetRValue(color), GetGValue(color), GetBValue(color));
1908
1909     out:
1910
1911     if(ddprimpal) IDirectDrawPalette_Release(ddprimpal);
1912     if(offscreen) IDirectDrawSurface_Release(offscreen);
1913     if(Surface1) IDirectDrawSurface_Release(Surface1);
1914     if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
1915     if(window) DestroyWindow(window);
1916 }
1917
1918 static void cubemap_test(IDirect3DDevice7 *device)
1919 {
1920     IDirect3D7 *d3d;
1921     IDirectDraw7 *ddraw;
1922     IDirectDrawSurface7 *cubemap, *surface;
1923     D3DDEVICEDESC7 d3dcaps;
1924     HRESULT hr;
1925     DWORD color;
1926     DDSURFACEDESC2 ddsd;
1927     DDBLTFX DDBltFx;
1928     DDSCAPS2 caps;
1929     static float quad[] = {
1930       -1.0,   -1.0,    0.1,    1.0,    0.0,    0.0, /* Lower left */
1931        0.0,   -1.0,    0.1,    1.0,    0.0,    0.0,
1932       -1.0,    0.0,    0.1,    1.0,    0.0,    0.0,
1933        0.0,    0.0,    0.1,    1.0,    0.0,    0.0,
1934
1935        0.0,   -1.0,    0.1,    0.0,    1.0,    0.0, /* Lower right */
1936        1.0,   -1.0,    0.1,    0.0,    1.0,    0.0,
1937        0.0,    0.0,    0.1,    0.0,    1.0,    0.0,
1938        1.0,    0.0,    0.1,    0.0,    1.0,    0.0,
1939
1940        0.0,    0.0,    0.1,    0.0,    0.0,    1.0, /* upper right */
1941        1.0,    0.0,    0.1,    0.0,    0.0,    1.0,
1942        0.0,    1.0,    0.1,    0.0,    0.0,    1.0,
1943        1.0,    1.0,    0.1,    0.0,    0.0,    1.0,
1944
1945       -1.0,    0.0,    0.1,   -1.0,    0.0,    0.0, /* Upper left */
1946        0.0,    0.0,    0.1,   -1.0,    0.0,    0.0,
1947       -1.0,    1.0,    0.1,   -1.0,    0.0,    0.0,
1948        0.0,    1.0,    0.1,   -1.0,    0.0,    0.0,
1949     };
1950
1951     memset(&DDBltFx, 0, sizeof(DDBltFx));
1952     DDBltFx.dwSize = sizeof(DDBltFx);
1953
1954     memset(&d3dcaps, 0, sizeof(d3dcaps));
1955     hr = IDirect3DDevice7_GetCaps(device, &d3dcaps);
1956     ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1957     if(!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1958     {
1959         skip("No cubemap support\n");
1960         return;
1961     }
1962
1963     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1964     ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
1965
1966     hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
1967     ok(hr == D3D_OK, "IDirect3DDevice7_GetDirect3D returned %08x\n", hr);
1968     hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **) &ddraw);
1969     ok(hr == D3D_OK, "IDirect3D7_QueryInterface returned %08x\n", hr);
1970     IDirect3D7_Release(d3d);
1971
1972
1973     memset(&ddsd, 0, sizeof(ddsd));
1974     ddsd.dwSize = sizeof(ddsd);
1975     ddsd.ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1976     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1977     ddsd.dwWidth = 16;
1978     ddsd.dwHeight = 16;
1979     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
1980     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES | DDSCAPS2_TEXTUREMANAGE;
1981     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1982     ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
1983     ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
1984     ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1985     ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
1986
1987     hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &cubemap, NULL);
1988     ok(hr == DD_OK, "IDirectDraw7_CreateSurface returned %08x\n", hr);
1989     IDirectDraw7_Release(ddraw);
1990
1991     /* Positive X */
1992     DDBltFx.dwFillColor = 0x00ff0000;
1993     hr = IDirectDrawSurface7_Blt(cubemap, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
1994     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
1995
1996     memset(&caps, 0, sizeof(caps));
1997     caps.dwCaps = DDSCAPS_TEXTURE;
1998     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
1999     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2000     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2001     DDBltFx.dwFillColor = 0x0000ffff;
2002     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2003     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2004
2005     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
2006     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2007     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2008     DDBltFx.dwFillColor = 0x0000ff00;
2009     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2010     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2011
2012     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
2013     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2014     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2015     DDBltFx.dwFillColor = 0x000000ff;
2016     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2017     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2018
2019     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
2020     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2021     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2022     DDBltFx.dwFillColor = 0x00ffff00;
2023     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2024     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2025
2026     caps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
2027     hr = IDirectDrawSurface_GetAttachedSurface(cubemap, &caps, &surface);
2028     ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned %08x\n", hr);
2029     DDBltFx.dwFillColor = 0x00ff00ff;
2030     hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL, &DDBltFx);
2031     ok(hr == DD_OK, "IDirectDrawSurface7_Blt returned %08x\n", hr);
2032
2033     hr = IDirect3DDevice7_SetTexture(device, 0, cubemap);
2034     ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2035     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2036     ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2037     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2038     ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2039
2040     hr = IDirect3DDevice7_BeginScene(device);
2041     ok(hr == DD_OK, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
2042     if(SUCCEEDED(hr))
2043     {
2044         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 0 * 6, 4, 0);
2045         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2046         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 4 * 6, 4, 0);
2047         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2048         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 8 * 6, 4, 0);
2049         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2050         hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, quad + 12* 6, 4, 0);
2051         ok(hr == DD_OK, "IDirect3DDevice7_DrawPrimitive returned %08x\n", hr);
2052
2053         hr = IDirect3DDevice7_EndScene(device);
2054         ok(hr == DD_OK, "IDirect3DDevice7_EndScene returned %08x\n", hr);
2055     }
2056     hr = IDirect3DDevice7_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2057     ok(hr == DD_OK, "IDirect3DDevice7_SetTextureStageState returned %08x\n", hr);
2058
2059     color = getPixelColor(device, 160, 360); /* lower left quad - positivex */
2060     ok(color == 0x00ff0000, "DDSCAPS2_CUBEMAP_POSITIVEX has color 0x%08x, expected 0x00ff0000\n", color);
2061     color = getPixelColor(device, 160, 120); /* upper left quad - negativex */
2062     ok(color == 0x0000ffff, "DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x%08x, expected 0x0000ffff\n", color);
2063     color = getPixelColor(device, 480, 360); /* lower right quad - positivey */
2064     ok(color == 0x00ff00ff, "DDSCAPS2_CUBEMAP_POSITIVEY has color 0x%08x, expected 0x00ff00ff\n", color);
2065     color = getPixelColor(device, 480, 120); /* upper right quad - positivez */
2066     ok(color == 0x000000ff, "DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x%08x, expected 0x000000ff\n", color);
2067     hr = IDirect3DDevice7_SetTexture(device, 0, NULL);
2068     ok(hr == DD_OK, "IDirect3DDevice7_SetTexture returned %08x\n", hr);
2069     IDirectDrawSurface7_Release(cubemap);
2070 }
2071
2072 START_TEST(visual)
2073 {
2074     HRESULT hr;
2075     DWORD color;
2076     if(!createObjects())
2077     {
2078         skip("Cannot initialize DirectDraw and Direct3D, skipping\n");
2079         return;
2080     }
2081
2082     /* Check for the reliability of the returned data */
2083     hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2084     if(FAILED(hr))
2085     {
2086         trace("Clear failed, can't assure correctness of the test results, skipping\n");
2087         goto cleanup;
2088     }
2089
2090     color = getPixelColor(Direct3DDevice, 1, 1);
2091     if(color !=0x00ff0000)
2092     {
2093         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
2094         goto cleanup;
2095     }
2096
2097     hr = IDirect3DDevice7_Clear(Direct3DDevice, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
2098     if(FAILED(hr))
2099     {
2100         trace("Clear failed, can't assure correctness of the test results, skipping\n");
2101         goto cleanup;
2102     }
2103
2104     color = getPixelColor(Direct3DDevice, 639, 479);
2105     if(color != 0x0000ddee)
2106     {
2107         trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
2108         goto cleanup;
2109     }
2110
2111     /* Now run the tests */
2112     lighting_test(Direct3DDevice);
2113     clear_test(Direct3DDevice);
2114     fog_test(Direct3DDevice);
2115     offscreen_test(Direct3DDevice);
2116     alpha_test(Direct3DDevice);
2117     rhw_zero_test(Direct3DDevice);
2118     cubemap_test(Direct3DDevice);
2119
2120     releaseObjects(); /* release DX7 interfaces to test D3D1 */
2121
2122     if(!D3D1_createObjects()) {
2123         skip("Cannot initialize D3D1, skipping\n");
2124     }
2125     else {
2126         D3D1_TextureMapBlendTest();
2127     }
2128     D3D1_releaseObjects();
2129
2130     p8_primary_test();
2131
2132     return ;
2133
2134 cleanup:
2135     releaseObjects();
2136 }