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