winealsa: Map ALSA errors to AUDCLNT_E_*.
[wine] / dlls / d3d8 / tests / visual.c
1 /*
2  * Copyright (C) 2005 Henri Verbeet
3  * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
21
22 #define COBJMACROS
23 #include <d3d8.h>
24 #include "wine/test.h"
25
26 static HMODULE d3d8_handle = 0;
27
28 static HWND create_window(void)
29 {
30     WNDCLASS wc = {0};
31     HWND ret;
32     wc.lpfnWndProc = DefWindowProc;
33     wc.lpszClassName = "d3d8_test_wc";
34     RegisterClass(&wc);
35
36     ret = CreateWindow("d3d8_test_wc", "d3d8_test",
37                        WS_POPUP | WS_SYSMENU , 20, 20, 640, 480, 0, 0, 0, 0);
38     ShowWindow(ret, SW_SHOW);
39     return ret;
40 }
41
42 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
43 {
44     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
45     c1 >>= 8; c2 >>= 8;
46     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
47     c1 >>= 8; c2 >>= 8;
48     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
49     c1 >>= 8; c2 >>= 8;
50     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
51     return TRUE;
52 }
53
54 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
55 {
56     DWORD ret;
57     IDirect3DTexture8 *tex = NULL;
58     IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
59     HRESULT hr;
60     D3DLOCKED_RECT lockedRect;
61     RECT rectToLock = {x, y, x+1, y+1};
62
63     hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
64     if(FAILED(hr) || !tex )  /* This is not a test */
65     {
66         trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr);
67         return 0xdeadbeef;
68     }
69     hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &surf);
70     if(FAILED(hr) || !tex )  /* This is not a test */
71     {
72         trace("Can't get surface from texture, hr=%#08x\n", hr);
73         ret = 0xdeadbeee;
74         goto out;
75     }
76
77     hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
78     if(FAILED(hr))
79     {
80         trace("Can't get the render target, hr=%#08x\n", hr);
81         ret = 0xdeadbeed;
82         goto out;
83     }
84     hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
85     if(FAILED(hr))
86     {
87         trace("Can't read the render target, hr=%#08x\n", hr);
88         ret = 0xdeadbeec;
89         goto out;
90     }
91
92     hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
93     if(FAILED(hr))
94     {
95         trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
96         ret = 0xdeadbeeb;
97         goto out;
98     }
99     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
100      * really important for these tests
101      */
102     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
103     hr = IDirect3DSurface8_UnlockRect(surf);
104     if(FAILED(hr))
105     {
106         trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
107     }
108
109 out:
110     if(backbuf) IDirect3DSurface8_Release(backbuf);
111     if(surf) IDirect3DSurface8_Release(surf);
112     if(tex) IDirect3DTexture8_Release(tex);
113     return ret;
114 }
115
116 static IDirect3DDevice8 *init_d3d8(void)
117 {
118     IDirect3D8 * (__stdcall * d3d8_create)(UINT SDKVersion) = 0;
119     IDirect3D8 *d3d8_ptr = 0;
120     IDirect3DDevice8 *device_ptr = 0;
121     D3DPRESENT_PARAMETERS present_parameters;
122     HRESULT hr;
123
124     d3d8_create = (void *)GetProcAddress(d3d8_handle, "Direct3DCreate8");
125     ok(d3d8_create != NULL, "Failed to get address of Direct3DCreate8\n");
126     if (!d3d8_create) return NULL;
127
128     d3d8_ptr = d3d8_create(D3D_SDK_VERSION);
129     if (!d3d8_ptr)
130     {
131         skip("could not create D3D8\n");
132         return NULL;
133     }
134
135     ZeroMemory(&present_parameters, sizeof(present_parameters));
136     present_parameters.Windowed = TRUE;
137     present_parameters.hDeviceWindow = create_window();
138     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
139     present_parameters.BackBufferWidth = 640;
140     present_parameters.BackBufferHeight = 480;
141     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
142     present_parameters.EnableAutoDepthStencil = TRUE;
143     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
144
145     hr = IDirect3D8_CreateDevice(d3d8_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
146             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
147     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL || broken(hr == D3DERR_NOTAVAILABLE), "IDirect3D_CreateDevice returned: %#08x\n", hr);
148
149     return device_ptr;
150 }
151
152 struct vertex
153 {
154     float x, y, z;
155     DWORD diffuse;
156 };
157
158 struct tvertex
159 {
160     float x, y, z, w;
161     DWORD diffuse;
162 };
163
164 struct nvertex
165 {
166     float x, y, z;
167     float nx, ny, nz;
168     DWORD diffuse;
169 };
170
171 static void lighting_test(IDirect3DDevice8 *device)
172 {
173     HRESULT hr;
174     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
175     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
176     DWORD color;
177
178     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
179                       0.0f, 1.0f, 0.0f, 0.0f,
180                       0.0f, 0.0f, 1.0f, 0.0f,
181                       0.0f, 0.0f, 0.0f, 1.0f };
182
183     struct vertex unlitquad[] =
184     {
185         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
186         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
187         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
188         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
189     };
190     struct vertex litquad[] =
191     {
192         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
193         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
194         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
195         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
196     };
197     struct nvertex unlitnquad[] =
198     {
199         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
200         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
201         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
202         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
203     };
204     struct nvertex litnquad[] =
205     {
206         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
207         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
208         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
209         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
210     };
211     WORD Indices[] = {0, 1, 2, 2, 3, 0};
212
213     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
214     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
215
216     /* Setup some states that may cause issues */
217     hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
218     ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
219     hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
220     ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
221     hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
222     ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
223     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
224     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
225     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
226     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
227     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
228     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
229     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
230     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
231     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
232     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
233     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
234     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
235     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
236     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
237     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
238     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
239
240     hr = IDirect3DDevice8_SetVertexShader(device, fvf);
241     ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
242
243     hr = IDirect3DDevice8_BeginScene(device);
244     ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr);
245     if(hr == D3D_OK)
246     {
247         /* No lights are defined... That means, lit vertices should be entirely black */
248         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
249         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
250         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
251                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
252         ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
253
254         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
255         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
256         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
257                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
258         ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
259
260         hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
261         ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed with %#08x\n", hr);
262
263         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
264         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
265         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
266                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
267         ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
268
269         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
270         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
271         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
272                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
273         ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr);
274
275         IDirect3DDevice8_EndScene(device);
276         ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %#08x\n", hr);
277     }
278
279     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
280     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
281     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
282     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
283     color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
284     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
285     color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
286     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
287
288     IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
289
290     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
292 }
293
294 static void clear_test(IDirect3DDevice8 *device)
295 {
296     /* Tests the correctness of clearing parameters */
297     HRESULT hr;
298     D3DRECT rect[2];
299     D3DRECT rect_negneg;
300     DWORD color;
301
302     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
304
305     /* Positive x, negative y */
306     rect[0].x1 = 0;
307     rect[0].y1 = 480;
308     rect[0].x2 = 320;
309     rect[0].y2 = 240;
310
311     /* Positive x, positive y */
312     rect[1].x1 = 0;
313     rect[1].y1 = 0;
314     rect[1].x2 = 320;
315     rect[1].y2 = 240;
316     /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
317      * is ignored, the positive is still cleared afterwards
318      */
319     hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
320     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
321
322     /* negative x, negative y */
323     rect_negneg.x1 = 640;
324     rect_negneg.y1 = 240;
325     rect_negneg.x2 = 320;
326     rect_negneg.y2 = 0;
327     hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
328     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
329
330     color = getPixelColor(device, 160, 360); /* lower left quad */
331     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
332     color = getPixelColor(device, 160, 120); /* upper left quad */
333     ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
334     color = getPixelColor(device, 480, 360); /* lower right quad  */
335     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
336     color = getPixelColor(device, 480, 120); /* upper right quad */
337     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
338
339     IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
340 }
341
342 struct sVertex {
343     float x, y, z;
344     DWORD diffuse;
345     DWORD specular;
346 };
347
348 struct sVertexT {
349     float x, y, z, rhw;
350     DWORD diffuse;
351     DWORD specular;
352 };
353
354 static void fog_test(IDirect3DDevice8 *device)
355 {
356     HRESULT hr;
357     DWORD color;
358     float start = 0.0, end = 1.0;
359
360     /* Gets full z based fog with linear fog, no fog with specular color */
361     struct sVertex untransformed_1[] = {
362         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
363         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
364         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
365         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
366     };
367     /* Ok, I am too lazy to deal with transform matrices */
368     struct sVertex untransformed_2[] = {
369         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
370         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
371         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
372         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
373     };
374     /* Untransformed ones. Give them a different diffuse color to make the test look
375      * nicer. It also makes making sure that they are drawn correctly easier.
376      */
377     struct sVertexT transformed_1[] = {
378         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
379         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
380         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
381         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
382     };
383     struct sVertexT transformed_2[] = {
384         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
385         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
386         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
387         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
388     };
389     WORD Indices[] = {0, 1, 2, 2, 3, 0};
390
391     D3DCAPS8 caps;
392     float ident_mat[16] =
393     {
394         1.0f, 0.0f, 0.0f, 0.0f,
395         0.0f, 1.0f, 0.0f, 0.0f,
396         0.0f, 0.0f, 1.0f, 0.0f,
397         0.0f, 0.0f, 0.0f, 1.0f
398     };
399     float world_mat1[16] =
400     {
401         1.0f, 0.0f,  0.0f, 0.0f,
402         0.0f, 1.0f,  0.0f, 0.0f,
403         0.0f, 0.0f,  1.0f, 0.0f,
404         0.0f, 0.0f, -0.5f, 1.0f
405     };
406     float world_mat2[16] =
407     {
408         1.0f, 0.0f, 0.0f, 0.0f,
409         0.0f, 1.0f, 0.0f, 0.0f,
410         0.0f, 0.0f, 1.0f, 0.0f,
411         0.0f, 0.0f, 1.0f, 1.0f
412     };
413     float proj_mat[16] =
414     {
415         1.0f, 0.0f,  0.0f, 0.0f,
416         0.0f, 1.0f,  0.0f, 0.0f,
417         0.0f, 0.0f,  1.0f, 0.0f,
418         0.0f, 0.0f, -1.0f, 1.0f
419     };
420
421     struct sVertex far_quad1[] =
422     {
423         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
424         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
425         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
426         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
427     };
428     struct sVertex far_quad2[] =
429     {
430         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
431         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
432         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
433         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
434     };
435
436     memset(&caps, 0, sizeof(caps));
437     hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
438     ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
439
440     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
441     ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
442
443     /* Setup initial states: No lighting, fog on, fog color */
444     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
445     ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
446     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
447     ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
448     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
449     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
450
451     /* First test: Both table fog and vertex fog off */
452     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
453     ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
454     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
455     ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
456
457     /* Start = 0, end = 1. Should be default, but set them */
458     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
459     ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
460     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
461     ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
462
463     if(IDirect3DDevice8_BeginScene(device) == D3D_OK)
464     {
465         hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
466         ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
467         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
468         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
469                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
470                                                      sizeof(untransformed_1[0]));
471         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
472
473         /* That makes it use the Z value */
474         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
475         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
476         /* Untransformed, vertex fog != none (or table fog != none):
477          * Use the Z value as input into the equation
478          */
479         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
480                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
481                                                      sizeof(untransformed_2[0]));
482         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
483
484         /* transformed verts */
485         hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
486         ok( hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
487         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
488         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
489                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
490                                                      sizeof(transformed_1[0]));
491         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
492
493         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
494         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
495         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
496          * equation
497          */
498         hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
499                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
500                                                      sizeof(transformed_2[0]));
501         ok(SUCCEEDED(hr), "IDirect3DDevice8_DrawIndexedPrimitiveUP returned %#x.\n", hr);
502
503         hr = IDirect3DDevice8_EndScene(device);
504         ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
505     }
506     else
507     {
508         ok(FALSE, "BeginScene failed\n");
509     }
510
511     color = getPixelColor(device, 160, 360);
512     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
513             "Untransformed vertex with no table or vertex fog has color %08x\n", color);
514     color = getPixelColor(device, 160, 120);
515     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
516             "Untransformed vertex with linear vertex fog has color %08x\n", color);
517     color = getPixelColor(device, 480, 120);
518     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
519             "Transformed vertex with linear vertex fog has color %08x\n", color);
520     color = getPixelColor(device, 480, 360);
521     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
522             "Transformed vertex with linear table fog has color %08x\n", color);
523
524     IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
525
526     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
527     {
528         /* A simple fog + non-identity world matrix test */
529         hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat1);
530         ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
531
532         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
533         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
534         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
535         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
536
537         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
538         ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
539
540         if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
541         {
542             hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
543             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
544
545             hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
546                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
547             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
548
549             hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
550                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
551             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
552
553             hr = IDirect3DDevice8_EndScene(device);
554             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
555         }
556         else
557         {
558             ok(FALSE, "BeginScene failed\n");
559         }
560
561         color = getPixelColor(device, 160, 360);
562         ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
563         color = getPixelColor(device, 160, 120);
564         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
565                 "Fogged out quad has color %08x\n", color);
566
567         IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
568
569         /* Test fog behavior with an orthogonal (but not identity) projection matrix */
570         hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) world_mat2);
571         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
572         hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) proj_mat);
573         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
574
575         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
576         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
577
578         if (IDirect3DDevice8_BeginScene(device) == D3D_OK)
579         {
580             hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
581             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
582
583             hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
584                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
585             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
586
587             hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
588                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
589             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
590
591             hr = IDirect3DDevice8_EndScene(device);
592             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
593         }
594         else
595         {
596             ok(FALSE, "BeginScene failed\n");
597         }
598
599         color = getPixelColor(device, 160, 360);
600         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
601         color = getPixelColor(device, 160, 120);
602         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
603                 "Fogged out quad has color %08x\n", color);
604
605         IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
606
607         hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) ident_mat);
608         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
609         hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) ident_mat);
610         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
611     }
612     else
613     {
614         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
615     }
616
617     /* Turn off the fog master switch to avoid confusing other tests */
618     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
619     ok(hr == D3D_OK, "Turning off fog calculations returned %#08x\n", hr);
620 }
621
622 static void present_test(IDirect3DDevice8 *device)
623 {
624     struct vertex quad[] =
625     {
626         {-1.0f, -1.0f,   0.9f,                          0xffff0000},
627         {-1.0f,  1.0f,   0.9f,                          0xffff0000},
628         { 1.0f, -1.0f,   0.1f,                          0xffff0000},
629         { 1.0f,  1.0f,   0.1f,                          0xffff0000},
630     };
631     HRESULT hr;
632     DWORD color;
633
634     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
635     * then call Present. Then clear the color buffer to make sure it has some defined content
636     * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
637     * by the depth value.
638     */
639     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
640     ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
641     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
642     ok(SUCCEEDED(hr), "IDirect3DDevice8_Present returned %#x.\n", hr);
643     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4f, 0);
644     ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear returned %#x.\n", hr);
645
646     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
647     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
648     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
649     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
650     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
651     ok(hr == D3D_OK, "IDirect3DDevice8_SetFVF returned %08x\n", hr);
652
653     hr = IDirect3DDevice8_BeginScene(device);
654     ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed with %08x\n", hr);
655     if(hr == D3D_OK)
656     {
657         /* No lights are defined... That means, lit vertices should be entirely black */
658         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
659         ok(hr == D3D_OK, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %08x\n", hr);
660
661         hr = IDirect3DDevice8_EndScene(device);
662         ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed with %08x\n", hr);
663     }
664
665     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
666     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
667
668     color = getPixelColor(device, 512, 240);
669     ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
670     color = getPixelColor(device, 64, 240);
671     ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
672
673     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
674     ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
675 }
676
677 static void test_rcp_rsq(IDirect3DDevice8 *device)
678 {
679     HRESULT hr;
680     DWORD shader;
681     DWORD color;
682     float constant[4] = {1.0, 1.0, 1.0, 2.0};
683
684     static const float quad[][3] = {
685         {-1.0f, -1.0f, 0.0f},
686         {-1.0f,  1.0f, 0.0f},
687         { 1.0f, -1.0f, 0.0f},
688         { 1.0f,  1.0f, 0.0f},
689     };
690
691     const DWORD rcp_test[] = {
692         0xfffe0101,                                         /* vs.1.1 */
693
694         0x0009fffe, 0x30303030, 0x30303030,                 /* Shaders have to have a minimal size. */
695         0x30303030, 0x30303030, 0x30303030,                 /* Add a filler comment. Usually D3DX8's*/
696         0x30303030, 0x30303030, 0x30303030,                 /* version comment makes the shader big */
697         0x00303030,                                         /* enough to make windows happy         */
698
699         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0 */
700         0x00000006, 0xd00f0000, 0xa0e40000,                 /* rcp oD0, c0 */
701         0x0000ffff                                          /* END */
702     };
703
704     const DWORD rsq_test[] = {
705         0xfffe0101,                                         /* vs.1.1 */
706
707         0x0009fffe, 0x30303030, 0x30303030,                 /* Shaders have to have a minimal size. */
708         0x30303030, 0x30303030, 0x30303030,                 /* Add a filler comment. Usually D3DX8's*/
709         0x30303030, 0x30303030, 0x30303030,                 /* version comment makes the shader big */
710         0x00303030,                                         /* enough to make windows happy         */
711
712         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0 */
713         0x00000007, 0xd00f0000, 0xa0e40000,                 /* rsq oD0, c0 */
714         0x0000ffff                                          /* END */
715     };
716
717     DWORD decl[] =
718     {
719         D3DVSD_STREAM(0),
720         D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),  /* D3DVSDE_POSITION, Register v0 */
721         D3DVSD_END()
722     };
723
724     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
725     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
726
727     hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
728     ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
729
730     IDirect3DDevice8_SetVertexShader(device, shader);
731     ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
732     IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
733
734     hr = IDirect3DDevice8_BeginScene(device);
735     ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
736     if(SUCCEEDED(hr))
737     {
738         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
739         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
740         hr = IDirect3DDevice8_EndScene(device);
741         ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
742     }
743
744     color = getPixelColor(device, 320, 240);
745     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), 4),
746             "RCP test returned color 0x%08x, expected 0x00808080.\n", color);
747
748     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
749     ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
750
751     IDirect3DDevice8_SetVertexShader(device, 0);
752     IDirect3DDevice8_DeleteVertexShader(device, shader);
753
754     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff996633, 0.0f, 0);
755     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
756
757     hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
758     ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %#08x\n", hr);
759
760     IDirect3DDevice8_SetVertexShader(device, shader);
761     ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
762     IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
763
764     hr = IDirect3DDevice8_BeginScene(device);
765     ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %#08x\n", hr);
766     if(SUCCEEDED(hr))
767     {
768         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
769         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%#08x)\n", hr);
770         hr = IDirect3DDevice8_EndScene(device);
771         ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %#08x\n", hr);
772     }
773
774     color = getPixelColor(device, 320, 240);
775     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), 4),
776             "RSQ test returned color 0x%08x, expected 0x00b4b4b4.\n", color);
777
778     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
779     ok(SUCCEEDED(hr), "Present failed (%#08x)\n", hr);
780
781     IDirect3DDevice8_SetVertexShader(device, 0);
782     IDirect3DDevice8_DeleteVertexShader(device, shader);
783 }
784
785 static void offscreen_test(IDirect3DDevice8 *device)
786 {
787     HRESULT hr;
788     IDirect3DTexture8 *offscreenTexture = NULL;
789     IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
790     DWORD color;
791
792     static const float quad[][5] = {
793         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
794         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
795         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
796         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
797     };
798
799     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
800     ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
801
802     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
803     ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
804
805     hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
806     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
807     if(!offscreenTexture) {
808         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
809         hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
810         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
811         if(!offscreenTexture) {
812             skip("Cannot create an offscreen render target\n");
813             goto out;
814         }
815     }
816
817     hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
818     ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
819     if(!backbuffer) {
820         goto out;
821     }
822
823     hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
824     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
825     if(!offscreen) {
826         goto out;
827     }
828
829     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
830     ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
831
832     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
833     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
834     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
835     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
836     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
837     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
838     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
839     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
840     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
841     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
842
843     if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
844         hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
845         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
846         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
847         ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
848
849         /* Draw without textures - Should result in a white quad */
850         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
851         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
852
853         hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
854         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %#08x\n", hr);
855         hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
856         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
857
858         /* This time with the texture */
859         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
860         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
861
862         IDirect3DDevice8_EndScene(device);
863     }
864
865     /* Center quad - should be white */
866     color = getPixelColor(device, 320, 240);
867     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
868     /* Some quad in the cleared part of the texture */
869     color = getPixelColor(device, 170, 240);
870     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
871     /* Part of the originally cleared back buffer */
872     color = getPixelColor(device, 10, 10);
873     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
874     if(0) {
875         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
876         * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
877         * the offscreen rendering mode this test would succeed or fail
878         */
879         color = getPixelColor(device, 10, 470);
880         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
881     }
882
883     IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
884
885 out:
886     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
887     ok(SUCCEEDED(hr), "IDirect3DDevice8_SetTexture returned %#x.\n", hr);
888
889     /* restore things */
890     if(backbuffer) {
891         hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
892         ok(SUCCEEDED(hr), "IDirect3DDevice8_SetRenderTarget returned %#x.\n", hr);
893         IDirect3DSurface8_Release(backbuffer);
894     }
895     if(offscreenTexture) {
896         IDirect3DTexture8_Release(offscreenTexture);
897     }
898     if(offscreen) {
899         IDirect3DSurface8_Release(offscreen);
900     }
901     if(depthstencil) {
902         IDirect3DSurface8_Release(depthstencil);
903     }
904 }
905
906 static void alpha_test(IDirect3DDevice8 *device)
907 {
908     HRESULT hr;
909     IDirect3DTexture8 *offscreenTexture;
910     IDirect3DSurface8 *backbuffer = NULL, *offscreen = NULL, *depthstencil = NULL;
911     DWORD color;
912
913     struct vertex quad1[] =
914     {
915         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
916         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
917         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
918         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
919     };
920     struct vertex quad2[] =
921     {
922         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
923         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
924         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
925         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
926     };
927     static const float composite_quad[][5] = {
928         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
929         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
930         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
931         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
932     };
933
934     /* Clear the render target with alpha = 0.5 */
935     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
936     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
937
938     hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
939     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
940
941     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
942     ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
943
944     hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
945     ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
946     if(!backbuffer) {
947         goto out;
948     }
949     hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
950     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
951     if(!offscreen) {
952         goto out;
953     }
954
955     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
956     ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
957
958     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
959     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
960     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
961     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
962     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
963     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
964     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
965     ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
966     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
967     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
968
969     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
970     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
971     if(IDirect3DDevice8_BeginScene(device) == D3D_OK) {
972
973         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
974         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
975         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
976         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
977         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
978         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
979         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
980
981         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
982         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
983         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
984         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
985         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
986         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
987
988         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
989          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
990          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
991         hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
992         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
993         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
994         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
995
996         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
997         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
998         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
999         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1000         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
1001         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1002
1003         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
1004         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1005         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
1006         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1007         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
1008         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1009
1010         hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
1011         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1012
1013         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
1014          * Disable alpha blending for the final composition
1015          */
1016         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1017         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1018         hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1019         ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1020
1021         hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
1022         ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1023         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
1024         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
1025         hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1026         ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1027
1028         hr = IDirect3DDevice8_EndScene(device);
1029         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
1030     }
1031
1032     color = getPixelColor(device, 160, 360);
1033     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1034        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
1035
1036     color = getPixelColor(device, 160, 120);
1037     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
1038        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
1039
1040     color = getPixelColor(device, 480, 360);
1041     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
1042        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
1043
1044     color = getPixelColor(device, 480, 120);
1045     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1046        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
1047
1048     IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1049
1050     out:
1051     /* restore things */
1052     if(backbuffer) {
1053         IDirect3DSurface8_Release(backbuffer);
1054     }
1055     if(offscreenTexture) {
1056         IDirect3DTexture8_Release(offscreenTexture);
1057     }
1058     if(offscreen) {
1059         IDirect3DSurface8_Release(offscreen);
1060     }
1061     if(depthstencil) {
1062         IDirect3DSurface8_Release(depthstencil);
1063     }
1064 }
1065
1066 static void p8_texture_test(IDirect3DDevice8 *device)
1067 {
1068     IDirect3D8 *d3d = NULL;
1069     HRESULT hr;
1070     IDirect3DTexture8 *texture = NULL, *texture2 = NULL;
1071     D3DLOCKED_RECT lr;
1072     unsigned char *data;
1073     DWORD color, red, green, blue;
1074     PALETTEENTRY table[256];
1075     D3DCAPS8 caps;
1076     UINT i;
1077     float quad[] = {
1078        -1.0f,      0.0f,    0.1f,    0.0f,   0.0f,
1079        -1.0f,      1.0f,    0.1f,    0.0f,   1.0f,
1080         1.0f,      0.0f,    0.1f,    1.0f,   0.0f,
1081         1.0f,      1.0f,    0.1f,    1.0f,   1.0f,
1082     };
1083     float quad2[] = {
1084        -1.0f,      -1.0f,   0.1f,    0.0f,   0.0f,
1085        -1.0f,      0.0f,    0.1f,    0.0f,   1.0f,
1086         1.0f,      -1.0f,   0.1f,    1.0f,   0.0f,
1087         1.0f,      0.0f,    0.1f,    1.0f,   1.0f,
1088     };
1089
1090     IDirect3DDevice8_GetDirect3D(device, &d3d);
1091
1092     if(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1093        D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK) {
1094            skip("D3DFMT_P8 textures not supported\n");
1095            goto out;
1096     }
1097
1098     hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1099                                         D3DPOOL_MANAGED, &texture2);
1100     ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1101     if(!texture2) {
1102         skip("Failed to create D3DFMT_P8 texture\n");
1103         goto out;
1104     }
1105
1106     memset(&lr, 0, sizeof(lr));
1107     hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
1108     ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1109     data = lr.pBits;
1110     *data = 1;
1111
1112     hr = IDirect3DTexture8_UnlockRect(texture2, 0);
1113     ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1114
1115     hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8,
1116                                         D3DPOOL_MANAGED, &texture);
1117     ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr = %08x\n", hr);
1118     if(!texture) {
1119         skip("Failed to create D3DFMT_P8 texture\n");
1120         goto out;
1121     }
1122
1123     memset(&lr, 0, sizeof(lr));
1124     hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
1125     ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
1126     data = lr.pBits;
1127     *data = 1;
1128
1129     hr = IDirect3DTexture8_UnlockRect(texture, 0);
1130     ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
1131
1132     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1133     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1134
1135     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1136     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1137
1138     /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
1139        alpha of every entry is set to 1.0, which MS says is required when there's no
1140        D3DPTEXTURECAPS_ALPHAPALETTE capability */
1141     for (i = 0; i < 256; i++) {
1142         table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1143         table[i].peFlags = 0xff;
1144     }
1145     table[1].peRed = 0xff;
1146     hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1147     ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1148
1149     table[1].peRed = 0;
1150     table[1].peBlue = 0xff;
1151     hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1152     ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1153
1154     hr = IDirect3DDevice8_BeginScene(device);
1155     ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1156     if(SUCCEEDED(hr)) {
1157         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1158         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1159         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1160         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1161
1162         hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1163         ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1164
1165         hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1166         ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1167
1168         hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1169         ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1170         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1171         ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1172
1173         hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
1174         ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1175         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1176         ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1177
1178         hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1179         ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1180         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1181         ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1182
1183         hr = IDirect3DDevice8_EndScene(device);
1184         ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1185     }
1186
1187     color = getPixelColor(device, 32, 32);
1188     red   = (color & 0x00ff0000) >> 16;
1189     green = (color & 0x0000ff00) >>  8;
1190     blue  = (color & 0x000000ff) >>  0;
1191     ok(red == 0xff && blue == 0 && green == 0,
1192        "got color %08x, expected 0x00ff0000\n", color);
1193
1194     color = getPixelColor(device, 32, 320);
1195     red   = (color & 0x00ff0000) >> 16;
1196     green = (color & 0x0000ff00) >>  8;
1197     blue  = (color & 0x000000ff) >>  0;
1198     ok(red == 0 && blue == 0xff && green == 0,
1199     "got color %08x, expected 0x000000ff\n", color);
1200
1201     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1202     ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1203
1204     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1205     ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1206
1207     hr = IDirect3DDevice8_BeginScene(device);
1208     ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1209     if(SUCCEEDED(hr)) {
1210         hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture2);
1211         ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1212
1213         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1214         ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1215
1216         hr = IDirect3DDevice8_EndScene(device);
1217         ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1218     }
1219
1220
1221     color = getPixelColor(device, 32, 32);
1222     red   = (color & 0x00ff0000) >> 16;
1223     green = (color & 0x0000ff00) >>  8;
1224     blue  = (color & 0x000000ff) >>  0;
1225     ok(red == 0 && blue == 0xff && green == 0,
1226     "got color %08x, expected 0x000000ff\n", color);
1227
1228     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1229     ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1230
1231     /* Test palettes with alpha */
1232     IDirect3DDevice8_GetDeviceCaps(device, &caps);
1233     if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
1234         skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
1235     } else {
1236         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
1237         ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
1238
1239         hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
1240         ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1241
1242         for (i = 0; i < 256; i++) {
1243             table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
1244             table[i].peFlags = 0xff;
1245         }
1246         table[1].peRed = 0xff;
1247         table[1].peFlags = 0x80;
1248         hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
1249         ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1250
1251         table[1].peRed = 0;
1252         table[1].peBlue = 0xff;
1253         table[1].peFlags = 0x80;
1254         hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
1255         ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
1256
1257         hr = IDirect3DDevice8_BeginScene(device);
1258         ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr = %08x\n", hr);
1259         if(SUCCEEDED(hr)) {
1260             hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1261             ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1262             hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1263             ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1264
1265             hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1266             ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
1267
1268             hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
1269             ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1270
1271             hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1272             ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1273
1274             hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
1275             ok(hr == D3D_OK, "IDirect3DDevice8_SetCurrentTexturePalette failed, hr = %08x\n", hr);
1276
1277             hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1278             ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr = %08x\n", hr);
1279
1280             hr = IDirect3DDevice8_EndScene(device);
1281             ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr = %08x\n", hr);
1282         }
1283
1284         color = getPixelColor(device, 32, 32);
1285         red   = (color & 0x00ff0000) >> 16;
1286         green = (color & 0x0000ff00) >>  8;
1287         blue  = (color & 0x000000ff) >>  0;
1288         ok(red >= 0x7e && red <= 0x81 && blue == 0 && green == 0,
1289         "got color %08x, expected 0x00800000 or near\n", color);
1290
1291         color = getPixelColor(device, 32, 320);
1292         red   = (color & 0x00ff0000) >> 16;
1293         green = (color & 0x0000ff00) >>  8;
1294         blue  = (color & 0x000000ff) >>  0;
1295         ok(red == 0 && blue >= 0x7e && blue <= 0x81 && green == 0,
1296         "got color %08x, expected 0x00000080 or near\n", color);
1297
1298         hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1299         ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
1300     }
1301
1302     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1303     ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture failed, hr = %08x\n", hr);
1304     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
1305     ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
1306
1307 out:
1308     if(texture) IDirect3DTexture8_Release(texture);
1309     if(texture2) IDirect3DTexture8_Release(texture2);
1310     IDirect3D8_Release(d3d);
1311 }
1312
1313 static void texop_test(IDirect3DDevice8 *device)
1314 {
1315     IDirect3DTexture8 *texture = NULL;
1316     D3DLOCKED_RECT locked_rect;
1317     D3DCOLOR color;
1318     D3DCAPS8 caps;
1319     HRESULT hr;
1320     unsigned int i;
1321
1322     static const struct {
1323         float x, y, z;
1324         D3DCOLOR diffuse;
1325         float s, t;
1326     } quad[] = {
1327         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
1328         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f,  1.0f},
1329         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00),  1.0f, -1.0f},
1330         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00),  1.0f,  1.0f}
1331     };
1332
1333     static const struct {
1334         D3DTEXTUREOP op;
1335         const char *name;
1336         DWORD caps_flag;
1337         D3DCOLOR result;
1338     } test_data[] = {
1339         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1340         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
1341         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
1342         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
1343         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1344         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1345
1346         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
1347         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
1348
1349         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
1350         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
1351         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1352         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
1353         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
1354         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1355         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
1356         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
1357         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
1358         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
1359         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
1360         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
1361         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
1362         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
1363         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
1364     };
1365
1366     memset(&caps, 0, sizeof(caps));
1367     hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1368     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
1369
1370     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
1371     ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
1372
1373     hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
1374     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
1375     hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
1376     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1377     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
1378     hr = IDirect3DTexture8_UnlockRect(texture, 0);
1379     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
1380     hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1381     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1382
1383     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
1384     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1385     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1386     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1387     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
1388     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1389
1390     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
1391     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
1392
1393     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1394     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1395     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
1396     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1397     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
1398     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
1399
1400     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1401     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1402
1403     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
1404     {
1405         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
1406         {
1407             skip("tex operation %s not supported\n", test_data[i].name);
1408             continue;
1409         }
1410
1411         hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
1412         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
1413
1414         hr = IDirect3DDevice8_BeginScene(device);
1415         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
1416
1417         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1418         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
1419
1420         hr = IDirect3DDevice8_EndScene(device);
1421         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
1422
1423         color = getPixelColor(device, 320, 240);
1424         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
1425                 test_data[i].name, color, test_data[i].result);
1426
1427         hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1428         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
1429
1430         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
1431         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
1432     }
1433
1434     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
1435     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
1436     if (texture) IDirect3DTexture8_Release(texture);
1437 }
1438
1439 /* This test tests depth clamping / clipping behaviour:
1440  *   - With software vertex processing, depth values are clamped to the
1441  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
1442  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
1443  *     same as regular vertices here.
1444  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
1445  *     Normal vertices are always clipped. Pretransformed vertices are
1446  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
1447  *   - The viewport's MinZ/MaxZ is irrelevant for this.
1448  */
1449 static void depth_clamp_test(IDirect3DDevice8 *device)
1450 {
1451     const struct tvertex quad1[] =
1452     {
1453         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
1454         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
1455         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
1456         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
1457     };
1458     const struct tvertex quad2[] =
1459     {
1460         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1461         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
1462         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1463         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
1464     };
1465     const struct tvertex quad3[] =
1466     {
1467         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
1468         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
1469         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
1470         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
1471     };
1472     const struct tvertex quad4[] =
1473     {
1474         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
1475         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
1476         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1477         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
1478     };
1479     const struct vertex quad5[] =
1480     {
1481         { -0.5f,   0.5f, 10.0f,       0xff14f914},
1482         {  0.5f,   0.5f, 10.0f,       0xff14f914},
1483         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
1484         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
1485     };
1486     const struct vertex quad6[] =
1487     {
1488         { -1.0f,   0.5f, 10.0f,       0xfff91414},
1489         {  1.0f,   0.5f, 10.0f,       0xfff91414},
1490         { -1.0f,  0.25f, 10.0f,       0xfff91414},
1491         {  1.0f,  0.25f, 10.0f,       0xfff91414},
1492     };
1493
1494     D3DVIEWPORT8 vp;
1495     D3DCOLOR color;
1496     D3DCAPS8 caps;
1497     HRESULT hr;
1498
1499     vp.X = 0;
1500     vp.Y = 0;
1501     vp.Width = 640;
1502     vp.Height = 480;
1503     vp.MinZ = 0.0;
1504     vp.MaxZ = 7.5;
1505
1506     hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1507     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1508
1509     hr = IDirect3DDevice8_SetViewport(device, &vp);
1510     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1511
1512     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
1513     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1514
1515     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1516     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1517     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1518     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1519     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1520     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1521     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1522     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1523
1524     hr = IDirect3DDevice8_BeginScene(device);
1525     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1526
1527     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1528     ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
1529
1530     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1531     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1532     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1533     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1534
1535     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1536     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1537
1538     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1539     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1540     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
1541     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1542
1543     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1544     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1545     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1546     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1547
1548     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
1549     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1550
1551     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1552     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1553
1554     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
1555     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1556
1557     hr = IDirect3DDevice8_EndScene(device);
1558     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1559
1560     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
1561     {
1562         color = getPixelColor(device, 75, 75);
1563         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1564         color = getPixelColor(device, 150, 150);
1565         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1566         color = getPixelColor(device, 320, 240);
1567         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1568         color = getPixelColor(device, 320, 330);
1569         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1570         color = getPixelColor(device, 320, 330);
1571         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
1572     }
1573     else
1574     {
1575         color = getPixelColor(device, 75, 75);
1576         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1577         color = getPixelColor(device, 150, 150);
1578         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
1579         color = getPixelColor(device, 320, 240);
1580         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
1581         color = getPixelColor(device, 320, 330);
1582         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1583         color = getPixelColor(device, 320, 330);
1584         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
1585     }
1586
1587     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1588     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1589
1590     vp.MinZ = 0.0;
1591     vp.MaxZ = 1.0;
1592     hr = IDirect3DDevice8_SetViewport(device, &vp);
1593     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1594 }
1595
1596 static void depth_buffer_test(IDirect3DDevice8 *device)
1597 {
1598     static const struct vertex quad1[] =
1599     {
1600         { -1.0,  1.0, 0.33f, 0xff00ff00},
1601         {  1.0,  1.0, 0.33f, 0xff00ff00},
1602         { -1.0, -1.0, 0.33f, 0xff00ff00},
1603         {  1.0, -1.0, 0.33f, 0xff00ff00},
1604     };
1605     static const struct vertex quad2[] =
1606     {
1607         { -1.0,  1.0, 0.50f, 0xffff00ff},
1608         {  1.0,  1.0, 0.50f, 0xffff00ff},
1609         { -1.0, -1.0, 0.50f, 0xffff00ff},
1610         {  1.0, -1.0, 0.50f, 0xffff00ff},
1611     };
1612     static const struct vertex quad3[] =
1613     {
1614         { -1.0,  1.0, 0.66f, 0xffff0000},
1615         {  1.0,  1.0, 0.66f, 0xffff0000},
1616         { -1.0, -1.0, 0.66f, 0xffff0000},
1617         {  1.0, -1.0, 0.66f, 0xffff0000},
1618     };
1619     static const DWORD expected_colors[4][4] =
1620     {
1621         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1622         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
1623         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
1624         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
1625     };
1626
1627     IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
1628     IDirect3DSurface8 *depth_stencil;
1629     unsigned int i, j;
1630     D3DVIEWPORT8 vp;
1631     D3DCOLOR color;
1632     HRESULT hr;
1633
1634     vp.X = 0;
1635     vp.Y = 0;
1636     vp.Width = 640;
1637     vp.Height = 480;
1638     vp.MinZ = 0.0;
1639     vp.MaxZ = 1.0;
1640
1641     hr = IDirect3DDevice8_SetViewport(device, &vp);
1642     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1643
1644     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1645     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1646     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1647     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1648     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1649     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1650     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1651     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1652     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1653     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1654
1655     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1656     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1657     hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1658     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1659     hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
1660             D3DMULTISAMPLE_NONE, FALSE, &rt1);
1661     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1662     hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1663             D3DMULTISAMPLE_NONE, FALSE, &rt2);
1664     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1665     hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1666             D3DMULTISAMPLE_NONE, FALSE, &rt3);
1667     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1668
1669     hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
1670     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1671     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
1672     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1673
1674     hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1675     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1676     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1677     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1678
1679     hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1680     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1681     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1682     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1683
1684     hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1685     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1686     hr = IDirect3DDevice8_BeginScene(device);
1687     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1688     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
1689     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1690     hr = IDirect3DDevice8_EndScene(device);
1691     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1692
1693     hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1694     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1695     IDirect3DSurface8_Release(depth_stencil);
1696     IDirect3DSurface8_Release(backbuffer);
1697     IDirect3DSurface8_Release(rt3);
1698     IDirect3DSurface8_Release(rt2);
1699     IDirect3DSurface8_Release(rt1);
1700
1701     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1702     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1703
1704     hr = IDirect3DDevice8_BeginScene(device);
1705     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1706     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
1707     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1708     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
1709     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1710     hr = IDirect3DDevice8_EndScene(device);
1711     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1712
1713     for (i = 0; i < 4; ++i)
1714     {
1715         for (j = 0; j < 4; ++j)
1716         {
1717             unsigned int x = 80 * ((2 * j) + 1);
1718             unsigned int y = 60 * ((2 * i) + 1);
1719             color = getPixelColor(device, x, y);
1720             ok(color_match(color, expected_colors[i][j], 0),
1721                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
1722         }
1723     }
1724
1725     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1726     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1727 }
1728
1729 /* Test that partial depth copies work the way they're supposed to. The clear
1730  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
1731  * the following draw should only copy back the part that was modified. */
1732 static void depth_buffer2_test(IDirect3DDevice8 *device)
1733 {
1734     static const struct vertex quad[] =
1735     {
1736         { -1.0,  1.0, 0.66f, 0xffff0000},
1737         {  1.0,  1.0, 0.66f, 0xffff0000},
1738         { -1.0, -1.0, 0.66f, 0xffff0000},
1739         {  1.0, -1.0, 0.66f, 0xffff0000},
1740     };
1741
1742     IDirect3DSurface8 *backbuffer, *rt1, *rt2;
1743     IDirect3DSurface8 *depth_stencil;
1744     unsigned int i, j;
1745     D3DVIEWPORT8 vp;
1746     D3DCOLOR color;
1747     HRESULT hr;
1748
1749     vp.X = 0;
1750     vp.Y = 0;
1751     vp.Width = 640;
1752     vp.Height = 480;
1753     vp.MinZ = 0.0;
1754     vp.MaxZ = 1.0;
1755
1756     hr = IDirect3DDevice8_SetViewport(device, &vp);
1757     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
1758
1759     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1760     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1761     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1762     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1763     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1764     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1765     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1766     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1767     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1768     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1769
1770     hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1771             D3DMULTISAMPLE_NONE, FALSE, &rt1);
1772     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1773     hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
1774             D3DMULTISAMPLE_NONE, FALSE, &rt2);
1775     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1776     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
1777     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1778     hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
1779     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1780
1781     hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
1782     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1783     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
1784     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1785
1786     hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1787     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1788     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
1789     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1790
1791     hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
1792     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1793     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
1794     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1795
1796     hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
1797     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1798     IDirect3DSurface8_Release(depth_stencil);
1799     IDirect3DSurface8_Release(backbuffer);
1800     IDirect3DSurface8_Release(rt2);
1801     IDirect3DSurface8_Release(rt1);
1802
1803     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1804     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1805
1806     hr = IDirect3DDevice8_BeginScene(device);
1807     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1808     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1809     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1810     hr = IDirect3DDevice8_EndScene(device);
1811     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1812
1813     for (i = 0; i < 4; ++i)
1814     {
1815         for (j = 0; j < 4; ++j)
1816         {
1817             unsigned int x = 80 * ((2 * j) + 1);
1818             unsigned int y = 60 * ((2 * i) + 1);
1819             color = getPixelColor(device, x, y);
1820             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
1821                     "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
1822         }
1823     }
1824
1825     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1826     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1827 }
1828
1829 static void intz_test(IDirect3DDevice8 *device)
1830 {
1831     static const DWORD ps_code[] =
1832     {
1833         0xffff0101,                                                             /* ps_1_1                       */
1834         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0   */
1835         0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0   */
1836         0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0   */
1837         0x00000042, 0xb00f0000,                                                 /* tex t0                       */
1838         0x00000042, 0xb00f0001,                                                 /* tex t1                       */
1839         0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001,                         /* dp3 t1.xyz, c0, t1           */
1840         0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001,                         /* mul r0.xyz, c1, t1           */
1841         0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000,             /* mad r0.xyz, c0, t0, r0       */
1842         0x40000001, 0x80080000, 0xa0aa0002,                                     /* +mov r0.w, c2.z              */
1843         0x0000ffff,                                                             /* end                          */
1844     };
1845     struct
1846     {
1847         float x, y, z;
1848         float s0, t0, p0;
1849         float s1, t1, p1, q1;
1850     }
1851     quad[] =
1852     {
1853         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1854         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1855         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1856         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1857     },
1858     half_quad_1[] =
1859     {
1860         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1861         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1862         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1863         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1864     },
1865     half_quad_2[] =
1866     {
1867         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
1868         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
1869         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
1870         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
1871     };
1872     struct
1873     {
1874         UINT x, y;
1875         D3DCOLOR color;
1876     }
1877     expected_colors[] =
1878     {
1879         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
1880         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
1881         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
1882         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
1883         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
1884         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
1885         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
1886         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
1887     };
1888
1889     IDirect3DSurface8 *original_ds, *original_rt, *rt;
1890     IDirect3DTexture8 *texture;
1891     IDirect3DSurface8 *ds;
1892     IDirect3D8 *d3d8;
1893     D3DCAPS8 caps;
1894     HRESULT hr;
1895     DWORD ps;
1896     UINT i;
1897
1898     hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1899     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1900     if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1901     {
1902         skip("No pixel shader 1.1 support, skipping INTZ test.\n");
1903         return;
1904     }
1905     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
1906     {
1907         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
1908         return;
1909     }
1910
1911     hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
1912     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
1913
1914     hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1915             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
1916     if (FAILED(hr))
1917     {
1918         skip("No INTZ support, skipping INTZ test.\n");
1919         return;
1920     }
1921
1922     IDirect3D8_Release(d3d8);
1923
1924     hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
1925     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
1926     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
1927     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
1928
1929     hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
1930             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
1931     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
1932     hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
1933             D3DMULTISAMPLE_NONE, FALSE, &rt);
1934     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
1935     hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
1936     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
1937
1938     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
1939             | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
1940     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
1941     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1942     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1943     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
1944     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1945     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1946     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1947     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1948     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
1949
1950     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
1951     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1952     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
1953     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1954     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1955     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1956     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
1957     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1958
1959     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
1960     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1961     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
1962     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1963     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
1964     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1965     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
1966     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1967     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
1968     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1969     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
1970             D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
1971     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
1972
1973     hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
1974     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
1975
1976     /* Render offscreen, using the INTZ texture as depth buffer */
1977     hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
1978     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1979     IDirect3DDevice8_SetPixelShader(device, 0);
1980     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
1981
1982     /* Setup the depth/stencil surface. */
1983     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
1984     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
1985
1986     hr = IDirect3DDevice8_BeginScene(device);
1987     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
1988     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1989     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
1990     hr = IDirect3DDevice8_EndScene(device);
1991     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
1992
1993     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
1994     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
1995     IDirect3DSurface8_Release(ds);
1996     hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
1997     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
1998     hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
1999     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2000     hr = IDirect3DDevice8_SetPixelShader(device, ps);
2001     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2002
2003     /* Read the depth values back. */
2004     hr = IDirect3DDevice8_BeginScene(device);
2005     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2006     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2007     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2008     hr = IDirect3DDevice8_EndScene(device);
2009     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2010
2011     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2012     {
2013         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2014         ok(color_match(color, expected_colors[i].color, 1),
2015                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2016                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2017     }
2018
2019     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2020     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2021
2022     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2023     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2024     hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2025     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2026     IDirect3DTexture8_Release(texture);
2027
2028     /* Render onscreen while using the INTZ texture as depth buffer */
2029     hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2030             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2031     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2032     hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2033     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2034     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2035     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2036     IDirect3DDevice8_SetPixelShader(device, 0);
2037     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2038
2039     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2040     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2041
2042     hr = IDirect3DDevice8_BeginScene(device);
2043     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2044     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2045     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2046     hr = IDirect3DDevice8_EndScene(device);
2047     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2048
2049     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2050     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2051     IDirect3DSurface8_Release(ds);
2052     hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2053     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2054     hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2055     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2056     hr = IDirect3DDevice8_SetPixelShader(device, ps);
2057     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2058
2059     /* Read the depth values back. */
2060     hr = IDirect3DDevice8_BeginScene(device);
2061     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2062     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2063     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2064     hr = IDirect3DDevice8_EndScene(device);
2065     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2066
2067     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2068     {
2069         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2070         ok(color_match(color, expected_colors[i].color, 1),
2071                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2072                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2073     }
2074
2075     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2076     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2077
2078     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2079     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2080     hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2081     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2082     IDirect3DTexture8_Release(texture);
2083
2084     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
2085     hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2086             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2087     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2088     hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2089     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2090     hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2091     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2092     IDirect3DDevice8_SetPixelShader(device, 0);
2093     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2094
2095     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2096     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2097
2098     hr = IDirect3DDevice8_BeginScene(device);
2099     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2100     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
2101     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2102     hr = IDirect3DDevice8_EndScene(device);
2103     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2104
2105     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2106     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2107
2108     hr = IDirect3DDevice8_BeginScene(device);
2109     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2110     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
2111     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2112     hr = IDirect3DDevice8_EndScene(device);
2113     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2114
2115     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2116     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2117     IDirect3DSurface8_Release(ds);
2118     hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2119     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2120     hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2121     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2122     hr = IDirect3DDevice8_SetPixelShader(device, ps);
2123     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2124
2125     /* Read the depth values back. */
2126     hr = IDirect3DDevice8_BeginScene(device);
2127     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2128     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2129     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2130     hr = IDirect3DDevice8_EndScene(device);
2131     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2132
2133     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2134     {
2135         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2136         ok(color_match(color, expected_colors[i].color, 1),
2137                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2138                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2139     }
2140
2141     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2142     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2143
2144     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2145     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2146     IDirect3DSurface8_Release(original_ds);
2147     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2148     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2149     hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2150     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2151     IDirect3DTexture8_Release(texture);
2152     hr = IDirect3DDevice8_SetPixelShader(device, 0);
2153     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2154     hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2155     ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2156
2157     IDirect3DSurface8_Release(original_rt);
2158     IDirect3DSurface8_Release(rt);
2159 }
2160
2161 static void shadow_test(IDirect3DDevice8 *device)
2162 {
2163     static const DWORD ps_code[] =
2164     {
2165         0xffff0101,                                                             /* ps_1_1                       */
2166         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0   */
2167         0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0   */
2168         0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0   */
2169         0x00000042, 0xb00f0000,                                                 /* tex t0                       */
2170         0x00000042, 0xb00f0001,                                                 /* tex t1                       */
2171         0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001,                         /* dp3 t1.xyz, c0, t1           */
2172         0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001,                         /* mul r0.xyz, c1, t1           */
2173         0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000,             /* mad r0.xyz, c0, t0, r0       */
2174         0x40000001, 0x80080000, 0xa0aa0002,                                     /* +mov r0.w, c2.z              */
2175         0x0000ffff,                                                             /* end                          */
2176     };
2177     struct
2178     {
2179         D3DFORMAT format;
2180         const char *name;
2181     }
2182     formats[] =
2183     {
2184         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
2185         {D3DFMT_D32,            "D3DFMT_D32"},
2186         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
2187         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
2188         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
2189         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
2190         {D3DFMT_D16,            "D3DFMT_D16"},
2191     };
2192     struct
2193     {
2194         float x, y, z;
2195         float s0, t0, p0;
2196         float s1, t1, p1, q1;
2197     }
2198     quad[] =
2199     {
2200         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
2201         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
2202         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
2203         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
2204     };
2205     struct
2206     {
2207         UINT x, y;
2208         D3DCOLOR color;
2209     }
2210     expected_colors[] =
2211     {
2212         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2213         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2214         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
2215         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2216         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
2217         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2218         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2219         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2220     };
2221
2222     IDirect3DSurface8 *original_ds, *original_rt, *rt;
2223     IDirect3D8 *d3d8;
2224     D3DCAPS8 caps;
2225     HRESULT hr;
2226     DWORD ps;
2227     UINT i;
2228
2229     hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2230     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2231     if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2232     {
2233         skip("No pixel shader 1.1 support, skipping shadow test.\n");
2234         return;
2235     }
2236
2237     hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2238     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
2239     hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2240     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
2241     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2242     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
2243
2244     hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
2245             D3DMULTISAMPLE_NONE, FALSE, &rt);
2246     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
2247     hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2248     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2249
2250     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2251             | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2252     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2253     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2254     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2255     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2256     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2257     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2258     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2259     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2260     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2261
2262     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2263     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2264     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2265     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2266     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2267     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2268     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2269     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2270
2271     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2272     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2273     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2274     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2275     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2276     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2277     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2278     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2279     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2280     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2281     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2282             D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2283     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2284
2285     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
2286     {
2287         D3DFORMAT format = formats[i].format;
2288         IDirect3DTexture8 *texture;
2289         IDirect3DSurface8 *ds;
2290         unsigned int j;
2291
2292         hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2293                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
2294         if (FAILED(hr)) continue;
2295
2296         hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
2297                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
2298         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2299
2300         hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
2301         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2302
2303         hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2304         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2305
2306         IDirect3DDevice8_SetPixelShader(device, 0);
2307         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2308
2309         /* Setup the depth/stencil surface. */
2310         hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
2311         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
2312
2313         hr = IDirect3DDevice8_BeginScene(device);
2314         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2315         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2316         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2317         hr = IDirect3DDevice8_EndScene(device);
2318         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2319
2320         hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2321         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2322         IDirect3DSurface8_Release(ds);
2323
2324         hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2325         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2326         hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2327         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2328
2329         hr = IDirect3DDevice8_SetPixelShader(device, ps);
2330         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2331
2332         /* Do the actual shadow mapping. */
2333         hr = IDirect3DDevice8_BeginScene(device);
2334         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2335         hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2336         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2337         hr = IDirect3DDevice8_EndScene(device);
2338         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2339
2340         hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2341         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2342         hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2343         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2344         IDirect3DTexture8_Release(texture);
2345
2346         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
2347         {
2348             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
2349             ok(color_match(color, expected_colors[j].color, 0),
2350                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
2351                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
2352                     formats[i].name, color);
2353         }
2354
2355         hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2356         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2357     }
2358
2359     hr = IDirect3DDevice8_SetPixelShader(device, 0);
2360     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2361     hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2362     ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2363
2364     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2365     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
2366     IDirect3DSurface8_Release(original_ds);
2367
2368     IDirect3DSurface8_Release(original_rt);
2369     IDirect3DSurface8_Release(rt);
2370
2371     IDirect3D8_Release(d3d8);
2372 }
2373
2374 static void multisample_copy_rects_test(IDirect3DDevice8 *device)
2375 {
2376     IDirect3DSurface8 *original_ds, *original_rt, *ds, *ds_plain, *rt, *readback;
2377     RECT src_rect = {64, 64, 128, 128};
2378     POINT dst_point = {96, 96};
2379     D3DLOCKED_RECT locked_rect;
2380     IDirect3D8 *d3d8;
2381     D3DCOLOR color;
2382     HRESULT hr;
2383
2384     hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2385     ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2386     hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2387             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2388     IDirect3D8_Release(d3d8);
2389     if (FAILED(hr))
2390     {
2391         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
2392         return;
2393     }
2394
2395     hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
2396             D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2397     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2398     hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2399             D3DMULTISAMPLE_2_SAMPLES, &ds);
2400     ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2401     hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
2402             D3DMULTISAMPLE_NONE, &ds_plain);
2403     ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
2404     hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
2405     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
2406
2407     hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2408     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2409     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2410     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2411
2412     hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2413     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2414
2415     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2416     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2417
2418     hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
2419     ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2420
2421     hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
2422     todo_wine ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2423
2424     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2425     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2426
2427     hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
2428     ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
2429
2430     hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
2431     ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
2432
2433     color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
2434     ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2435
2436     color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
2437     ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
2438
2439     hr = IDirect3DSurface8_UnlockRect(readback);
2440     ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
2441
2442     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2443     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
2444
2445     IDirect3DSurface8_Release(original_ds);
2446     IDirect3DSurface8_Release(original_rt);
2447     IDirect3DSurface8_Release(readback);
2448     IDirect3DSurface8_Release(ds_plain);
2449     IDirect3DSurface8_Release(ds);
2450     IDirect3DSurface8_Release(rt);
2451 }
2452
2453 static void resz_test(IDirect3DDevice8 *device)
2454 {
2455     IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
2456     IDirect3D8 *d3d8;
2457     D3DCAPS8 caps;
2458     HRESULT hr;
2459     unsigned int i;
2460     static const DWORD ps_code[] =
2461     {
2462         0xffff0101,                                                             /* ps_1_1                       */
2463         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0   */
2464         0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0   */
2465         0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0   */
2466         0x00000042, 0xb00f0000,                                                 /* tex t0                       */
2467         0x00000042, 0xb00f0001,                                                 /* tex t1                       */
2468         0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001,                         /* dp3 t1.xyz, c0, t1           */
2469         0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001,                         /* mul r0.xyz, c1, t1           */
2470         0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000,             /* mad r0.xyz, c0, t0, r0       */
2471         0x40000001, 0x80080000, 0xa0aa0002,                                     /* +mov r0.w, c2.z              */
2472         0x0000ffff,                                                             /* end                          */
2473     };
2474     struct
2475     {
2476         float x, y, z;
2477         float s0, t0, p0;
2478         float s1, t1, p1, q1;
2479     }
2480     quad[] =
2481     {
2482         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
2483         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
2484         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
2485         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
2486     };
2487     struct
2488     {
2489         UINT x, y;
2490         D3DCOLOR color;
2491     }
2492     expected_colors[] =
2493     {
2494         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2495         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2496         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2497         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2498         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
2499         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
2500         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
2501         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
2502     };
2503     IDirect3DTexture8 *texture;
2504     DWORD ps, value;
2505
2506     hr = IDirect3DDevice8_GetDirect3D(device, &d3d8);
2507     ok(SUCCEEDED(hr), "Failed to get d3d8 interface, hr %#x.\n", hr);
2508     hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2509             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2510     if (FAILED(hr))
2511     {
2512         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
2513         return;
2514     }
2515     hr = IDirect3D8_CheckDeviceMultiSampleType(d3d8, D3DADAPTER_DEFAULT,
2516             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES);
2517     if (FAILED(hr))
2518     {
2519         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
2520         return;
2521     }
2522     hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2523             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
2524     if (FAILED(hr))
2525     {
2526         skip("No INTZ support, skipping RESZ test.\n");
2527         return;
2528     }
2529     hr = IDirect3D8_CheckDeviceFormat(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
2530             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
2531     if (FAILED(hr))
2532     {
2533         skip("No RESZ support, skipping RESZ test.\n");
2534         return;
2535     }
2536     IDirect3D8_Release(d3d8);
2537
2538     hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2539     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
2540     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
2541     {
2542         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
2543         return;
2544     }
2545
2546     hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
2547     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2548     hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
2549     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
2550
2551     hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
2552             D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
2553     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2554     hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2555             D3DMULTISAMPLE_2_SAMPLES, &ds);
2556
2557     hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
2558             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
2559     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
2560     hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
2561     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
2562
2563     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
2564     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2565     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
2566     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2567
2568     hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2569     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2570     IDirect3DSurface8_Release(intz_ds);
2571     hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
2572     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
2573
2574     hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
2575             | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
2576     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
2577     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2578     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2579     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2580     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2581     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2582     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2583     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2584     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2585
2586     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
2587     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2588     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2589     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2590     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2591     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2592     hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2593     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2594
2595     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2596     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2597     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2598     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2599     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2600     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2601     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
2602     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2603     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
2604     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2605     hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
2606             D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
2607     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
2608
2609     /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
2610     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
2611     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2612
2613     hr = IDirect3DDevice8_BeginScene(device);
2614     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2615     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2616     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2617
2618     /* The destination depth texture has to be bound to sampler 0 */
2619     hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2620     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2621
2622     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
2623     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2624     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2625     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2626     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2627     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2628     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2629     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2630     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2631     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2632     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2633     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2634     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2635     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2636     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2637
2638     /* The actual multisampled depth buffer resolve happens here */
2639     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2640     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2641     hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
2642     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
2643
2644     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
2645     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2646     hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2647     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2648     hr = IDirect3DDevice8_SetPixelShader(device, ps);
2649     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2650
2651     /* Read the depth values back. */
2652     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2653     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2654     hr = IDirect3DDevice8_EndScene(device);
2655     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2656
2657     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2658     {
2659         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2660         ok(color_match(color, expected_colors[i].color, 1),
2661                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2662                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2663     }
2664
2665     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2666     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2667
2668     /* Test edge cases - try with no texture at all */
2669     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2670     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2671     hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2672     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2673     hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
2674     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2675
2676     hr = IDirect3DDevice8_BeginScene(device);
2677     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2678     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2679     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2680     hr = IDirect3DDevice8_EndScene(device);
2681     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2682
2683     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2684     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2685
2686     /* With a non-multisampled depth buffer */
2687     IDirect3DSurface8_Release(ds);
2688     IDirect3DSurface8_Release(rt);
2689     hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
2690             D3DMULTISAMPLE_NONE, &ds);
2691
2692     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
2693     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2694     hr = IDirect3DDevice8_SetPixelShader(device, 0);
2695     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2696
2697     hr = IDirect3DDevice8_BeginScene(device);
2698     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2699     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2700     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2701     hr = IDirect3DDevice8_EndScene(device);
2702     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2703
2704     hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2705     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2706
2707     hr = IDirect3DDevice8_BeginScene(device);
2708     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2709     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2710     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2711     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2712     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2713     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
2714     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2715     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2716     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2717     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
2718     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2719     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2720     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2721     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
2722     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
2723     hr = IDirect3DDevice8_EndScene(device);
2724     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2725
2726     hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
2727     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
2728
2729     hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
2730     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2731     hr = IDirect3DDevice8_SetPixelShader(device, ps);
2732     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2733
2734     /* Read the depth values back. */
2735     hr = IDirect3DDevice8_BeginScene(device);
2736     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2737     hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2738     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2739     hr = IDirect3DDevice8_EndScene(device);
2740     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2741
2742     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
2743     {
2744         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
2745         ok(color_match(color, expected_colors[i].color, 1),
2746                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
2747                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
2748     }
2749
2750     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2751     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2752
2753     hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, original_ds);
2754     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2755     IDirect3DSurface8_Release(ds);
2756     hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
2757     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2758     hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
2759     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
2760     IDirect3DTexture8_Release(texture);
2761     hr = IDirect3DDevice8_SetPixelShader(device, 0);
2762     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
2763     hr = IDirect3DDevice8_DeletePixelShader(device, ps);
2764     ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
2765     IDirect3DSurface8_Release(original_ds);
2766     IDirect3DSurface8_Release(original_rt);
2767 }
2768
2769 START_TEST(visual)
2770 {
2771     IDirect3DDevice8 *device_ptr;
2772     HRESULT hr;
2773     DWORD color;
2774     D3DCAPS8 caps;
2775
2776     d3d8_handle = LoadLibraryA("d3d8.dll");
2777     if (!d3d8_handle)
2778     {
2779         win_skip("Could not load d3d8.dll\n");
2780         return;
2781     }
2782
2783     device_ptr = init_d3d8();
2784     if (!device_ptr)
2785     {
2786         win_skip("Could not initialize direct3d\n");
2787         return;
2788     }
2789
2790     IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
2791
2792     /* Check for the reliability of the returned data */
2793     hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2794     if(FAILED(hr))
2795     {
2796         skip("Clear failed, can't assure correctness of the test results\n");
2797         goto cleanup;
2798     }
2799
2800     color = getPixelColor(device_ptr, 1, 1);
2801     if(color !=0x00ff0000)
2802     {
2803         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
2804         goto cleanup;
2805     }
2806     IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
2807
2808     hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
2809     if(FAILED(hr))
2810     {
2811         skip("Clear failed, can't assure correctness of the test results\n");
2812         goto cleanup;
2813     }
2814
2815     color = getPixelColor(device_ptr, 639, 479);
2816     if(color != 0x0000ddee)
2817     {
2818         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests\n", color);
2819         goto cleanup;
2820     }
2821     IDirect3DDevice8_Present(device_ptr, NULL, NULL, NULL, NULL);
2822
2823     /* Now run the real test */
2824     depth_clamp_test(device_ptr);
2825     lighting_test(device_ptr);
2826     clear_test(device_ptr);
2827     fog_test(device_ptr);
2828     present_test(device_ptr);
2829     offscreen_test(device_ptr);
2830     alpha_test(device_ptr);
2831
2832     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
2833     {
2834         test_rcp_rsq(device_ptr);
2835     }
2836     else
2837     {
2838         skip("No vs.1.1 support\n");
2839     }
2840
2841     p8_texture_test(device_ptr);
2842     texop_test(device_ptr);
2843     depth_buffer_test(device_ptr);
2844     depth_buffer2_test(device_ptr);
2845     intz_test(device_ptr);
2846     shadow_test(device_ptr);
2847     multisample_copy_rects_test(device_ptr);
2848     resz_test(device_ptr);
2849
2850 cleanup:
2851     if(device_ptr) {
2852         D3DDEVICE_CREATION_PARAMETERS creation_parameters;
2853         ULONG refcount;
2854
2855         IDirect3DDevice8_GetCreationParameters(device_ptr, &creation_parameters);
2856         DestroyWindow(creation_parameters.hFocusWindow);
2857         refcount = IDirect3DDevice8_Release(device_ptr);
2858         ok(!refcount, "Device has %u references left\n", refcount);
2859     }
2860 }