jscript: Get rid of BSTR in date.c.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 struct vec3
38 {
39     float x, y, z;
40 };
41
42 struct vec4
43 {
44     float x, y, z, w;
45 };
46
47 static HWND create_window(void)
48 {
49     WNDCLASS wc = {0};
50     HWND ret;
51     wc.lpfnWndProc = DefWindowProc;
52     wc.lpszClassName = "d3d9_test_wc";
53     RegisterClass(&wc);
54
55     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
56                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
57     ShowWindow(ret, SW_SHOW);
58     return ret;
59 }
60
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
62 {
63     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64     c1 >>= 8; c2 >>= 8;
65     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66     c1 >>= 8; c2 >>= 8;
67     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68     c1 >>= 8; c2 >>= 8;
69     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
70     return TRUE;
71 }
72
73 /* Locks a given surface and returns the color at (x,y).  It's the caller's
74  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
75 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
76 {
77     DWORD color;
78     HRESULT hr;
79     D3DSURFACE_DESC desc;
80     RECT rectToLock = {x, y, x+1, y+1};
81     D3DLOCKED_RECT lockedRect;
82
83     hr = IDirect3DSurface9_GetDesc(surface, &desc);
84     if(FAILED(hr))  /* This is not a test */
85     {
86         trace("Can't get the surface description, hr=%08x\n", hr);
87         return 0xdeadbeef;
88     }
89
90     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
91     if(FAILED(hr))  /* This is not a test */
92     {
93         trace("Can't lock the surface, hr=%08x\n", hr);
94         return 0xdeadbeef;
95     }
96     switch(desc.Format) {
97         case D3DFMT_A8R8G8B8:
98         {
99             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
100             break;
101         }
102         default:
103             trace("Error: unknown surface format: %d\n", desc.Format);
104             color = 0xdeadbeef;
105             break;
106     }
107     hr = IDirect3DSurface9_UnlockRect(surface);
108     if(FAILED(hr))
109     {
110         trace("Can't unlock the surface, hr=%08x\n", hr);
111     }
112     return color;
113 }
114
115 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
116 {
117     DWORD ret;
118     IDirect3DSurface9 *surf = NULL, *target = NULL;
119     HRESULT hr;
120     D3DLOCKED_RECT lockedRect;
121     RECT rectToLock = {x, y, x+1, y+1};
122
123     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
124             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
125     if (FAILED(hr) || !surf)
126     {
127         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
128         return 0xdeadbeef;
129     }
130
131     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
132     if(FAILED(hr))
133     {
134         trace("Can't get the render target, hr=%08x\n", hr);
135         ret = 0xdeadbeed;
136         goto out;
137     }
138
139     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
140     if (FAILED(hr))
141     {
142         trace("Can't read the render target data, hr=%08x\n", hr);
143         ret = 0xdeadbeec;
144         goto out;
145     }
146
147     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
148     if(FAILED(hr))
149     {
150         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
151         ret = 0xdeadbeeb;
152         goto out;
153     }
154
155     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
156      * really important for these tests
157      */
158     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
159     hr = IDirect3DSurface9_UnlockRect(surf);
160     if(FAILED(hr))
161     {
162         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
163     }
164
165 out:
166     if(target) IDirect3DSurface9_Release(target);
167     if(surf) IDirect3DSurface9_Release(surf);
168     return ret;
169 }
170
171 static IDirect3DDevice9 *init_d3d9(void)
172 {
173     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
174     IDirect3D9 *d3d9_ptr = 0;
175     IDirect3DDevice9 *device_ptr = 0;
176     D3DPRESENT_PARAMETERS present_parameters;
177     HRESULT hr;
178     D3DADAPTER_IDENTIFIER9 identifier;
179
180     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
181     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
182     if (!d3d9_create) return NULL;
183
184     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
185     if (!d3d9_ptr)
186     {
187         win_skip("could not create D3D9\n");
188         return NULL;
189     }
190
191     ZeroMemory(&present_parameters, sizeof(present_parameters));
192     present_parameters.Windowed = TRUE;
193     present_parameters.hDeviceWindow = create_window();
194     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
195     present_parameters.BackBufferWidth = 640;
196     present_parameters.BackBufferHeight = 480;
197     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
198     present_parameters.EnableAutoDepthStencil = TRUE;
199     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
200
201     memset(&identifier, 0, sizeof(identifier));
202     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
203     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
204     trace("Driver string: \"%s\"\n", identifier.Driver);
205     trace("Description string: \"%s\"\n", identifier.Description);
206     ok(identifier.Description[0] != '\0', "Empty driver description\n");
207     trace("Device name string: \"%s\"\n", identifier.DeviceName);
208     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
209     trace("Driver version %d.%d.%d.%d\n",
210           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
211           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
212
213     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
214             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
215     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
216             "Failed to create a device, hr %#x.\n", hr);
217
218     return device_ptr;
219 }
220
221 static void cleanup_device(IDirect3DDevice9 *device)
222 {
223     if (device)
224     {
225         D3DPRESENT_PARAMETERS present_parameters;
226         IDirect3DSwapChain9 *swapchain;
227         ULONG ref;
228
229         IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
230         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
231         IDirect3DSwapChain9_Release(swapchain);
232         ref = IDirect3DDevice9_Release(device);
233         ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
234         DestroyWindow(present_parameters.hDeviceWindow);
235     }
236 }
237
238 struct vertex
239 {
240     float x, y, z;
241     DWORD diffuse;
242 };
243
244 struct tvertex
245 {
246     float x, y, z, rhw;
247     DWORD diffuse;
248 };
249
250 struct nvertex
251 {
252     float x, y, z;
253     float nx, ny, nz;
254     DWORD diffuse;
255 };
256
257 static void lighting_test(IDirect3DDevice9 *device)
258 {
259     HRESULT hr;
260     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
261     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
262     DWORD color;
263     D3DMATERIAL9 material, old_material;
264     DWORD cop, carg;
265     DWORD old_colorwrite;
266
267     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
268                       0.0f, 1.0f, 0.0f, 0.0f,
269                       0.0f, 0.0f, 1.0f, 0.0f,
270                       0.0f, 0.0f, 0.0f, 1.0f };
271
272     struct vertex unlitquad[] =
273     {
274         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
275         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
276         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
277         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
278     };
279     struct vertex litquad[] =
280     {
281         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
282         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
283         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
284         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
285     };
286     struct nvertex unlitnquad[] =
287     {
288         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
289         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
290         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
291         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
292     };
293     struct nvertex litnquad[] =
294     {
295         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
296         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
297         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
298         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
299     };
300     WORD Indices[] = {0, 1, 2, 2, 3, 0};
301
302     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
304
305     /* Setup some states that may cause issues */
306     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
308     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
310     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
313     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
315     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
323     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
324     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
325     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
327     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
328     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
329     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
331     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
332
333     hr = IDirect3DDevice9_SetFVF(device, 0);
334     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
335
336     hr = IDirect3DDevice9_SetFVF(device, fvf);
337     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
338
339     hr = IDirect3DDevice9_BeginScene(device);
340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
341     if(hr == D3D_OK)
342     {
343         /* No lights are defined... That means, lit vertices should be entirely black */
344         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
345         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
346         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
347                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
348         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
349
350         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
351         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
352         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
353                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
354         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
355
356         hr = IDirect3DDevice9_SetFVF(device, nfvf);
357         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
358
359         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
360         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
361         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
362                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
363         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
364
365         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
366         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
368                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
369         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
370
371         hr = IDirect3DDevice9_EndScene(device);
372         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
373     }
374
375     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
376     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
377     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
378     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
379     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
380     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
381     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
382     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
383
384     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
385
386     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
387     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
388     memset(&material, 0, sizeof(material));
389     material.Diffuse.r = 0.0;
390     material.Diffuse.g = 0.0;
391     material.Diffuse.b = 0.0;
392     material.Diffuse.a = 1.0;
393     material.Ambient.r = 0.0;
394     material.Ambient.g = 0.0;
395     material.Ambient.b = 0.0;
396     material.Ambient.a = 0.0;
397     material.Specular.r = 0.0;
398     material.Specular.g = 0.0;
399     material.Specular.b = 0.0;
400     material.Specular.a = 0.0;
401     material.Emissive.r = 0.0;
402     material.Emissive.g = 0.0;
403     material.Emissive.b = 0.0;
404     material.Emissive.a = 0.0;
405     material.Power = 0.0;
406     hr = IDirect3DDevice9_SetMaterial(device, &material);
407     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
408
409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413
414     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
415     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
416     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
417     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422
423     hr = IDirect3DDevice9_BeginScene(device);
424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
425     if(SUCCEEDED(hr)) {
426         struct vertex lighting_test[] = {
427             {-1.0,   -1.0,   0.1,    0x8000ff00},
428             { 1.0,   -1.0,   0.1,    0x80000000},
429             {-1.0,    1.0,   0.1,    0x8000ff00},
430             { 1.0,    1.0,   0.1,    0x80000000}
431         };
432         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
433         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
436
437         hr = IDirect3DDevice9_EndScene(device);
438         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
439     }
440
441     color = getPixelColor(device, 320, 240);
442     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
443     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
444
445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
448     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
449     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
450     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
451     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
452     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
453     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
454     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
455     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
457     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
458     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
459 }
460
461 static void clear_test(IDirect3DDevice9 *device)
462 {
463     /* Tests the correctness of clearing parameters */
464     HRESULT hr;
465     D3DRECT rect[2];
466     D3DRECT rect_negneg;
467     DWORD color;
468     D3DVIEWPORT9 old_vp, vp;
469     RECT scissor;
470     DWORD oldColorWrite;
471     BOOL invalid_clear_failed = FALSE;
472
473     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
474     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
475
476     /* Positive x, negative y */
477     rect[0].x1 = 0;
478     rect[0].y1 = 480;
479     rect[0].x2 = 320;
480     rect[0].y2 = 240;
481
482     /* Positive x, positive y */
483     rect[1].x1 = 0;
484     rect[1].y1 = 0;
485     rect[1].x2 = 320;
486     rect[1].y2 = 240;
487     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
488      * returns D3D_OK, but ignores the rectangle silently
489      */
490     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
491     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
492     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
493
494     /* negative x, negative y */
495     rect_negneg.x1 = 640;
496     rect_negneg.y1 = 240;
497     rect_negneg.x2 = 320;
498     rect_negneg.y2 = 0;
499     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
500     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
502
503     color = getPixelColor(device, 160, 360); /* lower left quad */
504     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
505     color = getPixelColor(device, 160, 120); /* upper left quad */
506     if(invalid_clear_failed) {
507         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
508         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
509     } else {
510         /* If the negative rectangle was dropped silently, the correct ones are cleared */
511         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
512     }
513     color = getPixelColor(device, 480, 360); /* lower right quad  */
514     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
515     color = getPixelColor(device, 480, 120); /* upper right quad */
516     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
517
518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
519
520     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
521      * clear the red quad in the top left part of the render target. For some reason it
522      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
523      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
524      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
525      * pick some obvious value
526      */
527     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
528     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
529
530     /* Test how the viewport affects clears */
531     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
532     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
533     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
534     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
535
536     vp.X = 160;
537     vp.Y = 120;
538     vp.Width = 160;
539     vp.Height = 120;
540     vp.MinZ = 0.0;
541     vp.MaxZ = 1.0;
542     hr = IDirect3DDevice9_SetViewport(device, &vp);
543     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
544     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
545     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
546
547     vp.X = 320;
548     vp.Y = 240;
549     vp.Width = 320;
550     vp.Height = 240;
551     vp.MinZ = 0.0;
552     vp.MaxZ = 1.0;
553     hr = IDirect3DDevice9_SetViewport(device, &vp);
554     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555     rect[0].x1 = 160;
556     rect[0].y1 = 120;
557     rect[0].x2 = 480;
558     rect[0].y2 = 360;
559     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
563     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
564
565     color = getPixelColor(device, 158, 118);
566     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
567     color = getPixelColor(device, 162, 118);
568     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
569     color = getPixelColor(device, 158, 122);
570     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
571     color = getPixelColor(device, 162, 122);
572     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
573
574     color = getPixelColor(device, 318, 238);
575     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
576     color = getPixelColor(device, 322, 238);
577     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
578     color = getPixelColor(device, 318, 242);
579     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
580     color = getPixelColor(device, 322, 242);
581     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
582
583     color = getPixelColor(device, 478, 358);
584     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
585     color = getPixelColor(device, 482, 358);
586     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
587     color = getPixelColor(device, 478, 362);
588     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
589     color = getPixelColor(device, 482, 362);
590     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
591
592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
593
594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
595     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
596
597     scissor.left = 160;
598     scissor.right = 480;
599     scissor.top = 120;
600     scissor.bottom = 360;
601     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
602     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
604     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
605
606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
608     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
610
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
612     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
613
614     color = getPixelColor(device, 158, 118);
615     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
616     color = getPixelColor(device, 162, 118);
617     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
618     color = getPixelColor(device, 158, 122);
619     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
620     color = getPixelColor(device, 162, 122);
621     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 158, 358);
624     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
625     color = getPixelColor(device, 162, 358);
626     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
627     color = getPixelColor(device, 158, 358);
628     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
629     color = getPixelColor(device, 162, 362);
630     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
631
632     color = getPixelColor(device, 478, 118);
633     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
634     color = getPixelColor(device, 478, 122);
635     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
636     color = getPixelColor(device, 482, 122);
637     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
638     color = getPixelColor(device, 482, 358);
639     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
640
641     color = getPixelColor(device, 478, 358);
642     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
643     color = getPixelColor(device, 478, 362);
644     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
645     color = getPixelColor(device, 482, 358);
646     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
647     color = getPixelColor(device, 482, 362);
648     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
649
650     color = getPixelColor(device, 318, 238);
651     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
652     color = getPixelColor(device, 318, 242);
653     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
654     color = getPixelColor(device, 322, 238);
655     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
656     color = getPixelColor(device, 322, 242);
657     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
658
659     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
660
661     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
662     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
665
666     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
667     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
668     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
669
670     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
672
673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
675
676     /* Colorwriteenable does not affect the clear */
677     color = getPixelColor(device, 320, 240);
678     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
679
680     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
681 }
682
683 static void color_fill_test(IDirect3DDevice9 *device)
684 {
685     HRESULT hr;
686     IDirect3DSurface9 *backbuffer = NULL;
687     IDirect3DSurface9 *rt_surface = NULL;
688     IDirect3DSurface9 *offscreen_surface = NULL;
689     DWORD fill_color, color;
690
691     /* Test ColorFill on a the backbuffer (should pass) */
692     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
693     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
694     if(backbuffer)
695     {
696         fill_color = 0x112233;
697         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
698         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
699
700         color = getPixelColor(device, 0, 0);
701         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
702
703         IDirect3DSurface9_Release(backbuffer);
704     }
705
706     /* Test ColorFill on a render target surface (should pass) */
707     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
708     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
709     if(rt_surface)
710     {
711         fill_color = 0x445566;
712         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
713         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
714
715         color = getPixelColorFromSurface(rt_surface, 0, 0);
716         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
717
718         IDirect3DSurface9_Release(rt_surface);
719     }
720
721     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
722     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
723             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
724     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
725     if(offscreen_surface)
726     {
727         fill_color = 0x778899;
728         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
729         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
730
731         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
732         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
733
734         IDirect3DSurface9_Release(offscreen_surface);
735     }
736
737     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
738     offscreen_surface = NULL;
739     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
740             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
741     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
742     if(offscreen_surface)
743     {
744         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
745         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
746
747         IDirect3DSurface9_Release(offscreen_surface);
748     }
749 }
750
751 typedef struct {
752     float in[4];
753     DWORD out;
754 } test_data_t;
755
756 /*
757  *  c7      mova    ARGB            mov     ARGB
758  * -2.4     -2      0x00ffff00      -3      0x00ff0000
759  * -1.6     -2      0x00ffff00      -2      0x00ffff00
760  * -0.4      0      0x0000ffff      -1      0x0000ff00
761  *  0.4      0      0x0000ffff       0      0x0000ffff
762  *  1.6      2      0x00ff00ff       1      0x000000ff
763  *  2.4      2      0x00ff00ff       2      0x00ff00ff
764  */
765 static void test_mova(IDirect3DDevice9 *device)
766 {
767     static const DWORD mova_test[] = {
768         0xfffe0200,                                                             /* vs_2_0                       */
769         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
770         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
771         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
772         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
773         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
774         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
775         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
776         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
777         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
778         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
779         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
780         0x0000ffff                                                              /* END                          */
781     };
782     static const DWORD mov_test[] = {
783         0xfffe0101,                                                             /* vs_1_1                       */
784         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
785         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
786         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
787         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
788         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
789         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
790         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
791         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
792         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
793         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
794         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
795         0x0000ffff                                                              /* END                          */
796     };
797
798     static const test_data_t test_data[2][6] = {
799         {
800             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
801             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
802             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
803             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
804             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
805             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
806         },
807         {
808             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
809             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
810             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
811             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
812             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
813             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
814         }
815     };
816
817     static const float quad[][3] = {
818         {-1.0f, -1.0f, 0.0f},
819         {-1.0f,  1.0f, 0.0f},
820         { 1.0f, -1.0f, 0.0f},
821         { 1.0f,  1.0f, 0.0f},
822     };
823
824     static const D3DVERTEXELEMENT9 decl_elements[] = {
825         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
826         D3DDECL_END()
827     };
828
829     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
830     IDirect3DVertexShader9 *mova_shader = NULL;
831     IDirect3DVertexShader9 *mov_shader = NULL;
832     HRESULT hr;
833     UINT i, j;
834
835     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
836     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
837     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
838     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
839     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
840     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
841     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
842     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
843
844     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
845     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
846     for(j = 0; j < 2; ++j)
847     {
848         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
849         {
850             DWORD color;
851
852             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
853             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
854
855             hr = IDirect3DDevice9_BeginScene(device);
856             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
857
858             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
859             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
860
861             hr = IDirect3DDevice9_EndScene(device);
862             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
863
864             color = getPixelColor(device, 320, 240);
865             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
866                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
867
868             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
869             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
870
871             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
872             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
873         }
874         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
875         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
876     }
877
878     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
879     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
880
881     IDirect3DVertexDeclaration9_Release(vertex_declaration);
882     IDirect3DVertexShader9_Release(mova_shader);
883     IDirect3DVertexShader9_Release(mov_shader);
884 }
885
886 struct sVertex {
887     float x, y, z;
888     DWORD diffuse;
889     DWORD specular;
890 };
891
892 struct sVertexT {
893     float x, y, z, rhw;
894     DWORD diffuse;
895     DWORD specular;
896 };
897
898 static void fog_test(IDirect3DDevice9 *device)
899 {
900     HRESULT hr;
901     D3DCOLOR color;
902     float start = 0.0f, end = 1.0f;
903     D3DCAPS9 caps;
904     int i;
905
906     /* Gets full z based fog with linear fog, no fog with specular color */
907     struct sVertex untransformed_1[] = {
908         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
909         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
910         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
911         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
912     };
913     /* Ok, I am too lazy to deal with transform matrices */
914     struct sVertex untransformed_2[] = {
915         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
916         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
917         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
918         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
919     };
920     /* Untransformed ones. Give them a different diffuse color to make the test look
921      * nicer. It also makes making sure that they are drawn correctly easier.
922      */
923     struct sVertexT transformed_1[] = {
924         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
925         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
926         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
927         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
928     };
929     struct sVertexT transformed_2[] = {
930         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
931         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
932         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
933         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
934     };
935     struct vertex rev_fog_quads[] = {
936        {-1.0,   -1.0,   0.1,    0x000000ff},
937        {-1.0,    0.0,   0.1,    0x000000ff},
938        { 0.0,    0.0,   0.1,    0x000000ff},
939        { 0.0,   -1.0,   0.1,    0x000000ff},
940
941        { 0.0,   -1.0,   0.9,    0x000000ff},
942        { 0.0,    0.0,   0.9,    0x000000ff},
943        { 1.0,    0.0,   0.9,    0x000000ff},
944        { 1.0,   -1.0,   0.9,    0x000000ff},
945
946        { 0.0,    0.0,   0.4,    0x000000ff},
947        { 0.0,    1.0,   0.4,    0x000000ff},
948        { 1.0,    1.0,   0.4,    0x000000ff},
949        { 1.0,    0.0,   0.4,    0x000000ff},
950
951        {-1.0,    0.0,   0.7,    0x000000ff},
952        {-1.0,    1.0,   0.7,    0x000000ff},
953        { 0.0,    1.0,   0.7,    0x000000ff},
954        { 0.0,    0.0,   0.7,    0x000000ff},
955     };
956     WORD Indices[] = {0, 1, 2, 2, 3, 0};
957
958     const float ident_mat[16] =
959     {
960         1.0f, 0.0f, 0.0f, 0.0f,
961         0.0f, 1.0f, 0.0f, 0.0f,
962         0.0f, 0.0f, 1.0f, 0.0f,
963         0.0f, 0.0f, 0.0f, 1.0f
964     };
965     const float world_mat1[16] =
966     {
967         1.0f, 0.0f,  0.0f, 0.0f,
968         0.0f, 1.0f,  0.0f, 0.0f,
969         0.0f, 0.0f,  1.0f, 0.0f,
970         0.0f, 0.0f, -0.5f, 1.0f
971     };
972     const float world_mat2[16] =
973     {
974         1.0f, 0.0f, 0.0f, 0.0f,
975         0.0f, 1.0f, 0.0f, 0.0f,
976         0.0f, 0.0f, 1.0f, 0.0f,
977         0.0f, 0.0f, 1.0f, 1.0f
978     };
979     const float proj_mat[16] =
980     {
981         1.0f, 0.0f,  0.0f, 0.0f,
982         0.0f, 1.0f,  0.0f, 0.0f,
983         0.0f, 0.0f,  1.0f, 0.0f,
984         0.0f, 0.0f, -1.0f, 1.0f
985     };
986
987     const struct sVertex far_quad1[] =
988     {
989         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
990         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
991         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
992         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
993     };
994     const struct sVertex far_quad2[] =
995     {
996         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
997         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
998         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
999         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1000     };
1001
1002     memset(&caps, 0, sizeof(caps));
1003     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1004     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1005     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1006     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1007
1008     /* Setup initial states: No lighting, fog on, fog color */
1009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1010     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1011     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1012     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1013     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1014     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1015
1016     /* First test: Both table fog and vertex fog off */
1017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1018     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1020     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1021
1022     /* Start = 0, end = 1. Should be default, but set them */
1023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1024     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1026     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1027
1028     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1029     {
1030         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1031         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1032         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1033         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1034                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1035                                                      sizeof(untransformed_1[0]));
1036         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1037
1038         /* That makes it use the Z value */
1039         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1040         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1041         /* Untransformed, vertex fog != none (or table fog != none):
1042          * Use the Z value as input into the equation
1043          */
1044         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1045                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1046                                                      sizeof(untransformed_2[0]));
1047         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1048
1049         /* transformed verts */
1050         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1051         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1052         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1055                                                      sizeof(transformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057
1058         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1061          * equation
1062          */
1063         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1064                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1065                                                      sizeof(transformed_2[0]));
1066         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1067
1068         hr = IDirect3DDevice9_EndScene(device);
1069         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1070     }
1071     else
1072     {
1073         ok(FALSE, "BeginScene failed\n");
1074     }
1075
1076     color = getPixelColor(device, 160, 360);
1077     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1078     color = getPixelColor(device, 160, 120);
1079     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1080     color = getPixelColor(device, 480, 120);
1081     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1082     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1083     {
1084         color = getPixelColor(device, 480, 360);
1085         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1086     }
1087     else
1088     {
1089         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1090          * The settings above result in no fogging with vertex fog
1091          */
1092         color = getPixelColor(device, 480, 120);
1093         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1094         trace("Info: Table fog not supported by this device\n");
1095     }
1096     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1097
1098     /* Now test the special case fogstart == fogend */
1099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1100     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1101
1102     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1103     {
1104         start = 512;
1105         end = 512;
1106         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1107         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1108         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1109         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1110
1111         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1112         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1113         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1114         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1115         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1116         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1117
1118         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1119          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1120          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1121          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1122          * color and has fixed fogstart and fogend.
1123          */
1124         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1125                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1126                 sizeof(untransformed_1[0]));
1127         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1128         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1129                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1130                 sizeof(untransformed_2[0]));
1131         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1132
1133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1134         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1135         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1136         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1137                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1138                 sizeof(transformed_1[0]));
1139         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1140
1141         hr = IDirect3DDevice9_EndScene(device);
1142         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1143     }
1144     else
1145     {
1146         ok(FALSE, "BeginScene failed\n");
1147     }
1148     color = getPixelColor(device, 160, 360);
1149     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1150     color = getPixelColor(device, 160, 120);
1151     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1152     color = getPixelColor(device, 480, 120);
1153     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1154     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1155
1156     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1157      * but without shaders it seems to work everywhere
1158      */
1159     end = 0.2;
1160     start = 0.8;
1161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1162     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1163     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1164     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1165     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1166     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1167
1168     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1169      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1170      * so skip this for now
1171      */
1172     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1173         const char *mode = (i ? "table" : "vertex");
1174         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1175         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1176         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1177         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1178         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1179         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1180         hr = IDirect3DDevice9_BeginScene(device);
1181         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1182         if(SUCCEEDED(hr)) {
1183             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1184                                 4,  5,  6,  6,  7, 4,
1185                                 8,  9, 10, 10, 11, 8,
1186                             12, 13, 14, 14, 15, 12};
1187
1188             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1189                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1190                     sizeof(rev_fog_quads[0]));
1191             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1192
1193             hr = IDirect3DDevice9_EndScene(device);
1194             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1195         }
1196         color = getPixelColor(device, 160, 360);
1197         ok(color_match(color, 0x0000ff00, 1),
1198                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1199
1200         color = getPixelColor(device, 160, 120);
1201         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1202                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1203
1204         color = getPixelColor(device, 480, 120);
1205         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1206                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1207
1208         color = getPixelColor(device, 480, 360);
1209         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1210
1211         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1212
1213         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1214             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1215             break;
1216         }
1217     }
1218
1219     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1220     {
1221         /* A simple fog + non-identity world matrix test */
1222         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1223         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1224
1225         start = 0.0;
1226         end = 1.0;
1227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1228         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1229         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1230         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1232         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1234         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1235
1236         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1237         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1238
1239         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1240         {
1241             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1242             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1243
1244             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1245                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1246             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1247
1248             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1249                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1250             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1251
1252             hr = IDirect3DDevice9_EndScene(device);
1253             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1254         }
1255         else
1256         {
1257             ok(FALSE, "BeginScene failed\n");
1258         }
1259
1260         color = getPixelColor(device, 160, 360);
1261         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1262                 "Unfogged quad has color %08x\n", color);
1263         color = getPixelColor(device, 160, 120);
1264         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1265                 "Fogged out quad has color %08x\n", color);
1266
1267         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1268
1269         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1270         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1271         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1272         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1273         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1274
1275         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1276         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1277
1278         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1279         {
1280             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1281             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1282
1283             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1285             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1286
1287             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1288                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1289             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1290
1291             hr = IDirect3DDevice9_EndScene(device);
1292             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1293         }
1294         else
1295         {
1296             ok(FALSE, "BeginScene failed\n");
1297         }
1298
1299         color = getPixelColor(device, 160, 360);
1300         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1301         color = getPixelColor(device, 160, 120);
1302         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1303                 "Fogged out quad has color %08x\n", color);
1304
1305         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1306
1307         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1308         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1309         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1310         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1311     }
1312     else
1313     {
1314         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1315     }
1316
1317     /* Test RANGEFOG vs FOGTABLEMODE */
1318     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1319             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1320     {
1321         struct sVertex untransformed_3[] =
1322         {
1323             {-1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1324             {-1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1325             { 1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1326             { 1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1327         };
1328
1329         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1330         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1331         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1332         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1333
1334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1335         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1336
1337         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1338          * is not used, the fog coordinate will be equal to fogstart and the quad not
1339          * fogged. If range fog is used the fog coordinate will be slightly higher and
1340          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1341          * is calculated per vertex and interpolated, so even the center of the screen
1342          * where the difference doesn't matter will be fogged, but check the corners in
1343          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1344         start = 0.5f;
1345         end = 0.50001f;
1346         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1347         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1349         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1350
1351         /* Table fog: Range fog is not used */
1352         hr = IDirect3DDevice9_BeginScene(device);
1353         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1354         if (SUCCEEDED(hr))
1355         {
1356             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1357             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1358             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1359             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1360             hr = IDirect3DDevice9_EndScene(device);
1361             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1362         }
1363         color = getPixelColor(device, 10, 10);
1364         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1365         color = getPixelColor(device, 630, 10);
1366         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1367         color = getPixelColor(device, 10, 470);
1368         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1369         color = getPixelColor(device, 630, 470);
1370         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1371
1372         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1373         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1374
1375         /* Vertex fog: Rangefog is used */
1376         hr = IDirect3DDevice9_BeginScene(device);
1377         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1378         if (SUCCEEDED(hr))
1379         {
1380             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1381             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1382             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1383             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1384             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1385             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1386             hr = IDirect3DDevice9_EndScene(device);
1387             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1388         }
1389         color = getPixelColor(device, 10, 10);
1390         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1391                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1392         color = getPixelColor(device, 630, 10);
1393         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1394                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1395         color = getPixelColor(device, 10, 470);
1396         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1397                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1398         color = getPixelColor(device, 630, 470);
1399         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1400                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1401
1402         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1403         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1404
1405         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1406         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1407     }
1408     else
1409     {
1410         skip("Range fog or table fog not supported, skipping range fog tests\n");
1411     }
1412
1413     /* Turn off the fog master switch to avoid confusing other tests */
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1415     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1417     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1418     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1419     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1420 }
1421
1422 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1423  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1424  * regardless of the actual addressing mode set. The way this test works is
1425  * that we sample in one of the corners of the cubemap with filtering enabled,
1426  * and check the interpolated color. There are essentially two reasonable
1427  * things an implementation can do: Either pick one of the faces and
1428  * interpolate the edge texel with itself (i.e., clamp within the face), or
1429  * interpolate between the edge texels of the three involved faces. It should
1430  * never involve the border color or the other side (texcoord wrapping) of a
1431  * face in the interpolation. */
1432 static void test_cube_wrap(IDirect3DDevice9 *device)
1433 {
1434     static const float quad[][6] = {
1435         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1436         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1437         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1438         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1439     };
1440
1441     static const D3DVERTEXELEMENT9 decl_elements[] = {
1442         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1443         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1444         D3DDECL_END()
1445     };
1446
1447     static const struct {
1448         D3DTEXTUREADDRESS mode;
1449         const char *name;
1450     } address_modes[] = {
1451         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1452         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1453         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1454         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1455         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1456     };
1457
1458     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1459     IDirect3DCubeTexture9 *texture = NULL;
1460     IDirect3DSurface9 *surface = NULL;
1461     IDirect3DSurface9 *face_surface;
1462     D3DLOCKED_RECT locked_rect;
1463     HRESULT hr;
1464     UINT x;
1465     INT y, face;
1466
1467     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1468     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1469     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1470     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1471
1472     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1473             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1474     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1475
1476     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1477             D3DPOOL_DEFAULT, &texture, NULL);
1478     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1479
1480     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1481     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1482
1483     for (y = 0; y < 128; ++y)
1484     {
1485         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1486         for (x = 0; x < 64; ++x)
1487         {
1488             *ptr++ = 0xff0000ff;
1489         }
1490         for (x = 64; x < 128; ++x)
1491         {
1492             *ptr++ = 0xffff0000;
1493         }
1494     }
1495
1496     hr = IDirect3DSurface9_UnlockRect(surface);
1497     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1498
1499     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1500     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1501
1502     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1503     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1504
1505     IDirect3DSurface9_Release(face_surface);
1506
1507     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1508     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1509
1510     for (y = 0; y < 128; ++y)
1511     {
1512         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1513         for (x = 0; x < 64; ++x)
1514         {
1515             *ptr++ = 0xffff0000;
1516         }
1517         for (x = 64; x < 128; ++x)
1518         {
1519             *ptr++ = 0xff0000ff;
1520         }
1521     }
1522
1523     hr = IDirect3DSurface9_UnlockRect(surface);
1524     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1525
1526     /* Create cube faces */
1527     for (face = 1; face < 6; ++face)
1528     {
1529         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1530         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1531
1532         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1533         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1534
1535         IDirect3DSurface9_Release(face_surface);
1536     }
1537
1538     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1539     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1540
1541     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1542     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1543     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1544     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1545     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1546     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1547
1548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1550
1551     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1552     {
1553         DWORD color;
1554
1555         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1556         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1557         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1558         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1559
1560         hr = IDirect3DDevice9_BeginScene(device);
1561         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1562
1563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1564         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1565
1566         hr = IDirect3DDevice9_EndScene(device);
1567         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1568
1569         color = getPixelColor(device, 320, 240);
1570         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1571                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1572                 color, address_modes[x].name);
1573
1574         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1575         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1576
1577         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1578         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1579     }
1580
1581     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1582     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1583
1584     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1585     IDirect3DCubeTexture9_Release(texture);
1586     IDirect3DSurface9_Release(surface);
1587 }
1588
1589 static void offscreen_test(IDirect3DDevice9 *device)
1590 {
1591     HRESULT hr;
1592     IDirect3DTexture9 *offscreenTexture = NULL;
1593     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1594     DWORD color;
1595
1596     static const float quad[][5] = {
1597         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1598         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1599         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1600         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1601     };
1602
1603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1604     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1605
1606     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1607     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1608     if(!offscreenTexture) {
1609         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1610         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1611         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1612         if(!offscreenTexture) {
1613             skip("Cannot create an offscreen render target\n");
1614             goto out;
1615         }
1616     }
1617
1618     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1619     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1620     if(!backbuffer) {
1621         goto out;
1622     }
1623
1624     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1625     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1626     if(!offscreen) {
1627         goto out;
1628     }
1629
1630     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1631     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1632
1633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1634     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1635     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1636     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1637     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1638     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1639     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1640     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1643
1644     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1645         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1646         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1647         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1648         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1649
1650         /* Draw without textures - Should result in a white quad */
1651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1652         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1653
1654         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1655         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1656         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1657         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1658
1659         /* This time with the texture */
1660         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1661         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1662
1663         IDirect3DDevice9_EndScene(device);
1664     }
1665
1666     /* Center quad - should be white */
1667     color = getPixelColor(device, 320, 240);
1668     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669     /* Some quad in the cleared part of the texture */
1670     color = getPixelColor(device, 170, 240);
1671     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1672     /* Part of the originally cleared back buffer */
1673     color = getPixelColor(device, 10, 10);
1674     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1675     if(0) {
1676         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1677          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1678          * the offscreen rendering mode this test would succeed or fail
1679          */
1680         color = getPixelColor(device, 10, 470);
1681         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1682     }
1683
1684     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1685
1686 out:
1687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1688     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1689
1690     /* restore things */
1691     if (backbuffer)
1692     {
1693         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1694         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1695         IDirect3DSurface9_Release(backbuffer);
1696     }
1697     if(offscreenTexture) {
1698         IDirect3DTexture9_Release(offscreenTexture);
1699     }
1700     if(offscreen) {
1701         IDirect3DSurface9_Release(offscreen);
1702     }
1703 }
1704
1705 /* This test tests fog in combination with shaders.
1706  * What's tested: linear fog (vertex and table) with pixel shader
1707  *                linear table fog with non foggy vertex shader
1708  *                vertex fog with foggy vertex shader, non-linear
1709  *                fog with shader, non-linear fog with foggy shader,
1710  *                linear table fog with foggy shader
1711  */
1712 static void fog_with_shader_test(IDirect3DDevice9 *device)
1713 {
1714     HRESULT hr;
1715     DWORD color;
1716     union {
1717         float f;
1718         DWORD i;
1719     } start, end;
1720     unsigned int i, j;
1721
1722     /* basic vertex shader without fog computation ("non foggy") */
1723     static const DWORD vertex_shader_code1[] =
1724     {
1725         0xfffe0101,                                                             /* vs_1_1                       */
1726         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1727         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1728         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1729         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1730         0x0000ffff
1731     };
1732     /* basic vertex shader with reversed fog computation ("foggy") */
1733     static const DWORD vertex_shader_code2[] =
1734     {
1735         0xfffe0101,                                                             /* vs_1_1                        */
1736         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1737         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1738         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1739         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1740         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1741         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1742         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1743         0x0000ffff
1744     };
1745     /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1746     static const DWORD vertex_shader_code3[] =
1747     {
1748         0xfffe0200,                                                             /* vs_2_0                        */
1749         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1750         0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1751         0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1753         0x02000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1754         0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1755         0x03000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1756         0x0000ffff
1757     };
1758     /* basic pixel shader */
1759     static const DWORD pixel_shader_code[] =
1760     {
1761         0xffff0101,                                                             /* ps_1_1     */
1762         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0 */
1763         0x0000ffff
1764     };
1765     static const DWORD pixel_shader_code2[] =
1766     {
1767         0xffff0200,                                                             /* ps_2_0     */
1768         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0 */
1769         0x02000001, 0x800f0800, 0x90e40000,                                     /* mov oC0, v0 */
1770         0x0000ffff
1771     };
1772
1773     static struct vertex quad[] = {
1774         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1775         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1776         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1777         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1778     };
1779
1780     static const D3DVERTEXELEMENT9 decl_elements[] = {
1781         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1782         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1783         D3DDECL_END()
1784     };
1785
1786     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1787     IDirect3DVertexShader9      *vertex_shader[4]   = {NULL, NULL, NULL, NULL};
1788     IDirect3DPixelShader9       *pixel_shader[3]    = {NULL, NULL, NULL};
1789
1790     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1791     static const struct test_data_t {
1792         int vshader;
1793         int pshader;
1794         D3DFOGMODE vfog;
1795         D3DFOGMODE tfog;
1796         unsigned int color[11];
1797     } test_data[] = {
1798         /* only pixel shader: */
1799         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1800         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1801         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1802         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1803         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1806         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1814
1815         /* vertex shader */
1816         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1817         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1818          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1819         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1820         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1823         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1825
1826         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1827         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1830         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832
1833         /* vertex shader and pixel shader */
1834         /* The next 4 tests would read the fog coord output, but it isn't available.
1835          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1836          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1837          * These tests should be disabled if some other hardware behaves differently
1838          */
1839         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1840         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1841         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1842         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1843         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1844         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1845         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1846         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1847         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1848         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1850         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1851
1852         /* These use the Z coordinate with linear table fog */
1853         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1854         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1857         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1859         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1860         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1861         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1862         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1863         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1864         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1865
1866         /* Non-linear table fog without fog coord */
1867         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1868         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1869         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1870         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1871         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1872         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1873
1874         /* These tests fail on older Nvidia drivers */
1875         /* foggy vertex shader */
1876         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1877         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1878          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1879         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1880         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1881          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1882         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1883         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1884          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1885         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1886         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1887          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1888
1889         {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1890         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1891          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1892         {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1893         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1894          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1895         {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1896         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1897          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1898         {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1899         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1900          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1901
1902         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1903          * all using the fixed fog-coord linear fog
1904          */
1905         /* vs_1_1 with ps_1_1 */
1906         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1907         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1910         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1913         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1915         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1916         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1917          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1918
1919         /* vs_2_0 with ps_1_1 */
1920         {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1921         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1922          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1923         {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1924         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1925          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1926         {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1927         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1928          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1929         {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1930         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1931          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1932
1933         /* vs_1_1 with ps_2_0 */
1934         {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1935         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1936          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1937         {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1938         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1939          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1940         {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1941         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1942          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1943         {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1944         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1945          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1946
1947         /* vs_2_0 with ps_2_0 */
1948         {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1949         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1950          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1951         {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1952         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1953          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1954         {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1955         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1956          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1957         {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1958         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1959          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1960
1961         /* These use table fog. Here the shader-provided fog coordinate is
1962          * ignored and the z coordinate used instead
1963          */
1964         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1965         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1966         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1967         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1968         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1969         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1970         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1971         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1972         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1973     };
1974
1975     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1976     start.f=0.1f;
1977     end.f=0.9f;
1978
1979     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1980     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1981     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1982     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1983     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
1984     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1985     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1986     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1987     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
1988     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1989     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1990     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1991
1992     /* Setup initial states: No lighting, fog on, fog color */
1993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1994     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1996     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1998     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2000     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2001
2002     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2003     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2004     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2005     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2006
2007     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2009     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2011     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2012
2013     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2014     {
2015         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2016         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2017         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2018         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2020         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2021         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2022         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2023
2024         for(j=0; j < 11; j++)
2025         {
2026             /* Don't use the whole zrange to prevent rounding errors */
2027             quad[0].z = 0.001f + (float)j / 10.02f;
2028             quad[1].z = 0.001f + (float)j / 10.02f;
2029             quad[2].z = 0.001f + (float)j / 10.02f;
2030             quad[3].z = 0.001f + (float)j / 10.02f;
2031
2032             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2033             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2034
2035             hr = IDirect3DDevice9_BeginScene(device);
2036             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2037
2038             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2039             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2040
2041             hr = IDirect3DDevice9_EndScene(device);
2042             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2043
2044             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2045             color = getPixelColor(device, 128, 240);
2046             ok(color_match(color, test_data[i].color[j], 13),
2047                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2048                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2049
2050             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2051         }
2052     }
2053
2054     /* reset states */
2055     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2056     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2057     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2058     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2059     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2060     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2062     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2063
2064     IDirect3DVertexShader9_Release(vertex_shader[1]);
2065     IDirect3DVertexShader9_Release(vertex_shader[2]);
2066     IDirect3DVertexShader9_Release(vertex_shader[3]);
2067     IDirect3DPixelShader9_Release(pixel_shader[1]);
2068     IDirect3DPixelShader9_Release(pixel_shader[2]);
2069     IDirect3DVertexDeclaration9_Release(vertex_declaration);
2070 }
2071
2072 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2073     unsigned int i, x, y;
2074     HRESULT hr;
2075     IDirect3DTexture9 *texture[2] = {NULL, NULL};
2076     D3DLOCKED_RECT locked_rect;
2077
2078     /* Generate the textures */
2079     for(i=0; i<2; i++)
2080     {
2081         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2082                                             D3DPOOL_MANAGED, &texture[i], NULL);
2083         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2084
2085         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2086         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2087         for (y = 0; y < 128; ++y)
2088         {
2089             if(i)
2090             { /* Set up black texture with 2x2 texel white spot in the middle */
2091                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2092                 for (x = 0; x < 128; ++x)
2093                 {
2094                     if(y>62 && y<66 && x>62 && x<66)
2095                         *ptr++ = 0xffffffff;
2096                     else
2097                         *ptr++ = 0xff000000;
2098                 }
2099             }
2100             else
2101             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2102                * (if multiplied with bumpenvmat)
2103               */
2104                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2105                 for (x = 0; x < 128; ++x)
2106                 {
2107                     if(abs(x-64)>abs(y-64))
2108                     {
2109                         if(x < 64)
2110                             *ptr++ = 0xc000;
2111                         else
2112                             *ptr++ = 0x4000;
2113                     }
2114                     else
2115                     {
2116                         if(y < 64)
2117                             *ptr++ = 0x0040;
2118                         else
2119                             *ptr++ = 0x00c0;
2120                     }
2121                 }
2122             }
2123         }
2124         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2125         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2126
2127         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2128         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2129
2130         /* Disable texture filtering */
2131         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2132         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2133         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2134         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2135
2136         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2137         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2138         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2139         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2140     }
2141 }
2142
2143 /* test the behavior of the texbem instruction
2144  * with normal 2D and projective 2D textures
2145  */
2146 static void texbem_test(IDirect3DDevice9 *device)
2147 {
2148     HRESULT hr;
2149     DWORD color;
2150     int i;
2151
2152     static const DWORD pixel_shader_code[] = {
2153         0xffff0101,                         /* ps_1_1*/
2154         0x00000042, 0xb00f0000,             /* tex t0*/
2155         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2156         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2157         0x0000ffff
2158     };
2159     static const DWORD double_texbem_code[] =  {
2160         0xffff0103,                                         /* ps_1_3           */
2161         0x00000042, 0xb00f0000,                             /* tex t0           */
2162         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2163         0x00000042, 0xb00f0002,                             /* tex t2           */
2164         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2165         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2166         0x0000ffff                                          /* end              */
2167     };
2168
2169
2170     static const float quad[][7] = {
2171         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2172         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2173         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2174         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2175     };
2176     static const float quad_proj[][9] = {
2177         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2178         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2179         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2180         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2181     };
2182
2183     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2184         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2185         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2186         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2187         D3DDECL_END()
2188     },{
2189         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2190         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2191         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2192         D3DDECL_END()
2193     } };
2194
2195     /* use asymmetric matrix to test loading */
2196     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2197
2198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2199     IDirect3DPixelShader9       *pixel_shader       = NULL;
2200     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2201     D3DLOCKED_RECT locked_rect;
2202
2203     generate_bumpmap_textures(device);
2204
2205     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2206     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2207     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2208     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2209     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2210
2211     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2212     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2213
2214     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2216
2217     for(i=0; i<2; i++)
2218     {
2219         if(i)
2220         {
2221             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2222             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2223         }
2224
2225         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2226         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2227         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2228         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2229
2230         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2231         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2232         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2233         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2234
2235         hr = IDirect3DDevice9_BeginScene(device);
2236         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2237
2238         if(!i)
2239             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2240         else
2241             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2242         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2243
2244         hr = IDirect3DDevice9_EndScene(device);
2245         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2246
2247         color = getPixelColor(device, 320-32, 240);
2248         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2249         color = getPixelColor(device, 320+32, 240);
2250         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2251         color = getPixelColor(device, 320, 240-32);
2252         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2253         color = getPixelColor(device, 320, 240+32);
2254         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2255
2256         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2257         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2258
2259         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2260         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2261         IDirect3DPixelShader9_Release(pixel_shader);
2262
2263         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2264         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2265         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2266     }
2267
2268     /* clean up */
2269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2270     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2271
2272     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2273     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2274
2275     for(i=0; i<2; i++)
2276     {
2277         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2278         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2279         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2280         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2281         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2282         IDirect3DTexture9_Release(texture);
2283     }
2284
2285     /* Test double texbem */
2286     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2287     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2288     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2289     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2290     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2291     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2292     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2293     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2294
2295     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2296     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2297     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2298     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2299
2300     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2301     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2302
2303     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2304     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2305     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2306     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2307     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2308     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2309
2310     {
2311         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2312 #define tex  0x00ff0000
2313 #define tex1 0x0000ff00
2314 #define origin 0x000000ff
2315         static const DWORD pixel_data[] = {
2316             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2317             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2318             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2319             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2320             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2321             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2322             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2323             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2324         };
2325 #undef tex1
2326 #undef tex2
2327 #undef origin
2328
2329         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2330         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2331         for(i = 0; i < 8; i++) {
2332             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2333         }
2334         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2335         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2336     }
2337
2338     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2339     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2340     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2341     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2342     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2343     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2344     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2345     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2346     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2347     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2348     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2349     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2350
2351     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2352     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2353     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2354     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2355     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2356     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2357     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2358     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2359     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2360     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2361
2362     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2363     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2364     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2365     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2366     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2367     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2368     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2369     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2370     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2371     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2372
2373     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2374     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2375     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2376     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2377     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2378     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2379     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2380     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2381     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2382     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2383     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2384     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2385     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2386     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2387     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2388     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2389
2390     hr = IDirect3DDevice9_BeginScene(device);
2391     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2392     if(SUCCEEDED(hr)) {
2393         static const float double_quad[] = {
2394             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2395              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2396             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2397              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2398         };
2399
2400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2401         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2402         hr = IDirect3DDevice9_EndScene(device);
2403         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2404     }
2405     color = getPixelColor(device, 320, 240);
2406     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2407
2408     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2409     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2410     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2412     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2414     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2415     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2416     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2417     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2418
2419     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2420     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2421
2422     IDirect3DPixelShader9_Release(pixel_shader);
2423     IDirect3DTexture9_Release(texture);
2424     IDirect3DTexture9_Release(texture1);
2425     IDirect3DTexture9_Release(texture2);
2426 }
2427
2428 static void z_range_test(IDirect3DDevice9 *device)
2429 {
2430     const struct vertex quad[] =
2431     {
2432         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2433         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2434         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2435         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2436     };
2437     const struct vertex quad2[] =
2438     {
2439         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2440         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2441         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2442         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2443     };
2444
2445     const struct tvertex quad3[] =
2446     {
2447         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2448         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2449         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2450         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2451     };
2452     const struct tvertex quad4[] =
2453     {
2454         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2455         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2456         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2457         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2458     };
2459     HRESULT hr;
2460     DWORD color;
2461     IDirect3DVertexShader9 *shader;
2462     IDirect3DVertexDeclaration9 *decl;
2463     D3DCAPS9 caps;
2464     const DWORD shader_code[] = {
2465         0xfffe0101,                                     /* vs_1_1           */
2466         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2467         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2468         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2469         0x0000ffff                                      /* end              */
2470     };
2471     static const D3DVERTEXELEMENT9 decl_elements[] = {
2472         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2473         D3DDECL_END()
2474     };
2475
2476     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2477
2478     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2479      * then call Present. Then clear the color buffer to make sure it has some defined content
2480      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2481      * by the depth value.
2482      */
2483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2485     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2486     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2487     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2488     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2489
2490     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2491     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2492     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2493     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2494     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2495     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2497     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2498     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2499     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2500
2501     hr = IDirect3DDevice9_BeginScene(device);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2503     if(hr == D3D_OK)
2504     {
2505         /* Test the untransformed vertex path */
2506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2507         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2508         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2509         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2510         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2511         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2512
2513         /* Test the transformed vertex path */
2514         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2515         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2516
2517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2518         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2519         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2520         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2522         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2523
2524         hr = IDirect3DDevice9_EndScene(device);
2525         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2526     }
2527
2528     /* Do not test the exact corner pixels, but go pretty close to them */
2529
2530     /* Clipped because z > 1.0 */
2531     color = getPixelColor(device, 28, 238);
2532     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2533     color = getPixelColor(device, 28, 241);
2534     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2535     {
2536         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2537     }
2538     else
2539     {
2540         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2541     }
2542
2543     /* Not clipped, > z buffer clear value(0.75) */
2544     color = getPixelColor(device, 31, 238);
2545     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2546     color = getPixelColor(device, 31, 241);
2547     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2548     color = getPixelColor(device, 100, 238);
2549     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2550     color = getPixelColor(device, 100, 241);
2551     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2552
2553     /* Not clipped, < z buffer clear value */
2554     color = getPixelColor(device, 104, 238);
2555     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2556     color = getPixelColor(device, 104, 241);
2557     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2558     color = getPixelColor(device, 318, 238);
2559     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2560     color = getPixelColor(device, 318, 241);
2561     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2562
2563     /* Clipped because z < 0.0 */
2564     color = getPixelColor(device, 321, 238);
2565     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2566     color = getPixelColor(device, 321, 241);
2567     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2568     {
2569         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2570     }
2571     else
2572     {
2573         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2574     }
2575
2576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2577     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2578
2579     /* Test the shader path */
2580     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2581         skip("Vertex shaders not supported\n");
2582         goto out;
2583     }
2584     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2585     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2586     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2587     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2588
2589     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2590
2591     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2592     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2593     hr = IDirect3DDevice9_SetVertexShader(device, shader);
2594     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2595
2596     hr = IDirect3DDevice9_BeginScene(device);
2597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2598     if(hr == D3D_OK)
2599     {
2600         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2601         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2602         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2604         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2605         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2606         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2607         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2609         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2610
2611         hr = IDirect3DDevice9_EndScene(device);
2612         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2613     }
2614
2615     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2619
2620     IDirect3DVertexDeclaration9_Release(decl);
2621     IDirect3DVertexShader9_Release(shader);
2622
2623     /* Z < 1.0 */
2624     color = getPixelColor(device, 28, 238);
2625     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2626
2627     /* 1.0 < z < 0.75 */
2628     color = getPixelColor(device, 31, 238);
2629     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2630     color = getPixelColor(device, 100, 238);
2631     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2632
2633     /* 0.75 < z < 0.0 */
2634     color = getPixelColor(device, 104, 238);
2635     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2636     color = getPixelColor(device, 318, 238);
2637     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2638
2639     /* 0.0 < z */
2640     color = getPixelColor(device, 321, 238);
2641     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2642
2643     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2644     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2645
2646     out:
2647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2648     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2650     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2652     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2653 }
2654
2655 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2656 {
2657     D3DSURFACE_DESC desc;
2658     D3DLOCKED_RECT l;
2659     HRESULT hr;
2660     unsigned int x, y;
2661     DWORD *mem;
2662
2663     memset(&desc, 0, sizeof(desc));
2664     memset(&l, 0, sizeof(l));
2665     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2666     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2667     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2668     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2669     if(FAILED(hr)) return;
2670
2671     for(y = 0; y < desc.Height; y++)
2672     {
2673         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2674         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2675         {
2676             mem[x] = color;
2677         }
2678     }
2679     hr = IDirect3DSurface9_UnlockRect(surface);
2680     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2681 }
2682
2683 /* This tests a variety of possible StretchRect() situations */
2684 static void stretchrect_test(IDirect3DDevice9 *device)
2685 {
2686     HRESULT hr;
2687     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2688     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2689     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2690     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2691     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2692     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2693     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2694     IDirect3DSurface9 *orig_rt = NULL;
2695     IDirect3DSurface9 *backbuffer = NULL;
2696     DWORD color;
2697
2698     RECT src_rect64 = {0, 0, 64, 64};
2699     RECT src_rect64_flipy = {0, 64, 64, 0};
2700     RECT dst_rect64 = {0, 0, 64, 64};
2701     RECT dst_rect64_flipy = {0, 64, 64, 0};
2702
2703     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2704     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2705     if(!orig_rt) {
2706         goto out;
2707     }
2708
2709     /* Create our temporary surfaces in system memory */
2710     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2711     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2713     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2714
2715     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2716     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2717     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2718     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2720     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2721     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2722
2723     /* Create render target surfaces */
2724     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2725     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2726     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2727     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2728     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2729     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2730     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2731     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2732
2733     /* Create render target textures */
2734     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2735     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2736     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2737     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2738     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2739     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2740     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2741     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2742     if (tex_rt32) {
2743         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2744         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2745     }
2746     if (tex_rt64) {
2747         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2748         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2749     }
2750     if (tex_rt_dest64) {
2751         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2752         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2753     }
2754     if (tex_rt_dest64) {
2755         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2756         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2757     }
2758
2759     /* Create regular textures in D3DPOOL_DEFAULT */
2760     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2761     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2762     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2763     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2764     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2765     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2766     if (tex32) {
2767         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2768         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2769     }
2770     if (tex64) {
2771         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2772         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2773     }
2774     if (tex_dest64) {
2775         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2776         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2777     }
2778
2779     /*********************************************************************
2780      * Tests for when the source parameter is an offscreen plain surface *
2781      *********************************************************************/
2782
2783     /* Fill the offscreen 64x64 surface with green */
2784     if (surf_offscreen64)
2785         fill_surface(surf_offscreen64, 0xff00ff00);
2786
2787     /* offscreenplain ==> offscreenplain, same size */
2788     if(surf_offscreen64 && surf_offscreen_dest64) {
2789         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2790         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2791
2792         if (hr == D3D_OK) {
2793             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2794             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2795         }
2796
2797         /* Blit without scaling */
2798         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2799         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2800
2801         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2802         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2803         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2804
2805         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2806         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2807         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808     }
2809
2810     /* offscreenplain ==> rendertarget texture, same size */
2811     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2812         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2813         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2814
2815         /* We can't lock rendertarget textures, so copy to our temp surface first */
2816         if (hr == D3D_OK) {
2817             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2818             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2819         }
2820
2821         if (hr == D3D_OK) {
2822             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2823             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2824         }
2825
2826         /* Blit without scaling */
2827         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2828         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829
2830         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2831         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2832         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833
2834         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2835         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2836         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837     }
2838
2839     /* offscreenplain ==> rendertarget surface, same size */
2840     if(surf_offscreen64 && surf_rt_dest64) {
2841         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2842         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2843
2844         if (hr == D3D_OK) {
2845             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2846             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2847         }
2848
2849         /* Blit without scaling */
2850         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2851         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852
2853         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2855         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856
2857         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2858         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2859         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860     }
2861
2862     /* offscreenplain ==> texture, same size (should fail) */
2863     if(surf_offscreen64 && surf_tex_dest64) {
2864         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2865         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2866     }
2867
2868     /* Fill the smaller offscreen surface with red */
2869     fill_surface(surf_offscreen32, 0xffff0000);
2870
2871     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2872     if(surf_offscreen32 && surf_offscreen64) {
2873         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2874         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2875     }
2876
2877     /* offscreenplain ==> rendertarget texture, scaling */
2878     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2879         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2880         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2881
2882         /* We can't lock rendertarget textures, so copy to our temp surface first */
2883         if (hr == D3D_OK) {
2884             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2885             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2886         }
2887
2888         if (hr == D3D_OK) {
2889             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2890             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2891         }
2892     }
2893
2894     /* offscreenplain ==> rendertarget surface, scaling */
2895     if(surf_offscreen32 && surf_rt_dest64) {
2896         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2897         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2898
2899         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2900         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2901     }
2902
2903     /* offscreenplain ==> texture, scaling (should fail) */
2904     if(surf_offscreen32 && surf_tex_dest64) {
2905         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2907     }
2908
2909     /************************************************************
2910      * Tests for when the source parameter is a regular texture *
2911      ************************************************************/
2912
2913     /* Fill the surface of the regular texture with blue */
2914     if (surf_tex64 && surf_temp64) {
2915         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2916         fill_surface(surf_temp64, 0xff0000ff);
2917         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2918         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2919     }
2920
2921     /* texture ==> offscreenplain, same size */
2922     if(surf_tex64 && surf_offscreen64) {
2923         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2924         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2925     }
2926
2927     /* texture ==> rendertarget texture, same size */
2928     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2929         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2930         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2931
2932         /* We can't lock rendertarget textures, so copy to our temp surface first */
2933         if (hr == D3D_OK) {
2934             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2935             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2936         }
2937
2938         if (hr == D3D_OK) {
2939             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2940             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2941         }
2942
2943         /* Blit without scaling */
2944         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2945         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2946
2947         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2948         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2949         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2950
2951         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2952         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2953         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2954     }
2955
2956     /* texture ==> rendertarget surface, same size */
2957     if(surf_tex64 && surf_rt_dest64) {
2958         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2959         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960
2961         if (hr == D3D_OK) {
2962             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2963             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2964         }
2965
2966         /* Blit without scaling */
2967         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2968         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2969
2970         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2971         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2972         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973
2974         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2975         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2976         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977     }
2978
2979     /* texture ==> texture, same size (should fail) */
2980     if(surf_tex64 && surf_tex_dest64) {
2981         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2982         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2983     }
2984
2985     /* Fill the surface of the smaller regular texture with red */
2986     if (surf_tex32 && surf_temp32) {
2987         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2988         fill_surface(surf_temp32, 0xffff0000);
2989         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2990         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2991     }
2992
2993     /* texture ==> offscreenplain, scaling (should fail) */
2994     if(surf_tex32 && surf_offscreen64) {
2995         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2996         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2997     }
2998
2999     /* texture ==> rendertarget texture, scaling */
3000     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3001         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3002         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3003
3004         /* We can't lock rendertarget textures, so copy to our temp surface first */
3005         if (hr == D3D_OK) {
3006             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3007             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3008         }
3009
3010         if (hr == D3D_OK) {
3011             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3012             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3013         }
3014     }
3015
3016     /* texture ==> rendertarget surface, scaling */
3017     if(surf_tex32 && surf_rt_dest64) {
3018         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3019         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3020
3021         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3022         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3023     }
3024
3025     /* texture ==> texture, scaling (should fail) */
3026     if(surf_tex32 && surf_tex_dest64) {
3027         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3028         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3029     }
3030
3031     /*****************************************************************
3032      * Tests for when the source parameter is a rendertarget texture *
3033      *****************************************************************/
3034
3035     /* Fill the surface of the rendertarget texture with white */
3036     if (surf_tex_rt64 && surf_temp64) {
3037         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3038         fill_surface(surf_temp64, 0xffffffff);
3039         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3040         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3041     }
3042
3043     /* rendertarget texture ==> offscreenplain, same size */
3044     if(surf_tex_rt64 && surf_offscreen64) {
3045         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3046         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3047     }
3048
3049     /* rendertarget texture ==> rendertarget texture, same size */
3050     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3051         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3052         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3053
3054         /* We can't lock rendertarget textures, so copy to our temp surface first */
3055         if (hr == D3D_OK) {
3056             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3057             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3058         }
3059
3060         if (hr == D3D_OK) {
3061             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3062             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3063         }
3064
3065         /* Blit without scaling */
3066         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3067         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3068
3069         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3070         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3071         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3072
3073         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3074         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3075         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3076     }
3077
3078     /* rendertarget texture ==> rendertarget surface, same size */
3079     if(surf_tex_rt64 && surf_rt_dest64) {
3080         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3081         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082
3083         if (hr == D3D_OK) {
3084             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3085             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3086         }
3087
3088         /* Blit without scaling */
3089         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3090         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091
3092         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3093         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3094         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095
3096         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3097         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3098         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3099     }
3100
3101     /* rendertarget texture ==> texture, same size (should fail) */
3102     if(surf_tex_rt64 && surf_tex_dest64) {
3103         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3104         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3105     }
3106
3107     /* Fill the surface of the smaller rendertarget texture with red */
3108     if (surf_tex_rt32 && surf_temp32) {
3109         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3110         fill_surface(surf_temp32, 0xffff0000);
3111         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3112         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3113     }
3114
3115     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3116     if(surf_tex_rt32 && surf_offscreen64) {
3117         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3118         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3119     }
3120
3121     /* rendertarget texture ==> rendertarget texture, scaling */
3122     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3123         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3124         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3125
3126         /* We can't lock rendertarget textures, so copy to our temp surface first */
3127         if (hr == D3D_OK) {
3128             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3129             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3130         }
3131
3132         if (hr == D3D_OK) {
3133             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3134             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3135         }
3136     }
3137
3138     /* rendertarget texture ==> rendertarget surface, scaling */
3139     if(surf_tex_rt32 && surf_rt_dest64) {
3140         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3141         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3142
3143         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3144         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3145     }
3146
3147     /* rendertarget texture ==> texture, scaling (should fail) */
3148     if(surf_tex_rt32 && surf_tex_dest64) {
3149         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3150         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3151     }
3152
3153     /*****************************************************************
3154      * Tests for when the source parameter is a rendertarget surface *
3155      *****************************************************************/
3156
3157     /* Fill the surface of the rendertarget surface with black */
3158     if (surf_rt64)
3159         fill_surface(surf_rt64, 0xff000000);
3160
3161     /* rendertarget texture ==> offscreenplain, same size */
3162     if(surf_rt64 && surf_offscreen64) {
3163         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3164         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3165     }
3166
3167     /* rendertarget surface ==> rendertarget texture, same size */
3168     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3169         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3170         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171
3172         /* We can't lock rendertarget textures, so copy to our temp surface first */
3173         if (hr == D3D_OK) {
3174             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3175             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3176         }
3177
3178         if (hr == D3D_OK) {
3179             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3180             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3181         }
3182
3183         /* Blit without scaling */
3184         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3185         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3186
3187         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3188         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3189         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3190
3191         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3192         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3193         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3194     }
3195
3196     /* rendertarget surface ==> rendertarget surface, same size */
3197     if(surf_rt64 && surf_rt_dest64) {
3198         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3199         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3200
3201         if (hr == D3D_OK) {
3202             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3203             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3204         }
3205
3206         /* Blit without scaling */
3207         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3208         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3209
3210         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3211         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3212         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3213
3214         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3215         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3216         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3217     }
3218
3219     /* rendertarget surface ==> texture, same size (should fail) */
3220     if(surf_rt64 && surf_tex_dest64) {
3221         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3222         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3223     }
3224
3225     /* Fill the surface of the smaller rendertarget texture with red */
3226     if (surf_rt32)
3227         fill_surface(surf_rt32, 0xffff0000);
3228
3229     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3230     if(surf_rt32 && surf_offscreen64) {
3231         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3232         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3233     }
3234
3235     /* rendertarget surface ==> rendertarget texture, scaling */
3236     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3237         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3238         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3239
3240         /* We can't lock rendertarget textures, so copy to our temp surface first */
3241         if (hr == D3D_OK) {
3242             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3243             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3244         }
3245
3246         if (hr == D3D_OK) {
3247             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3248             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3249         }
3250     }
3251
3252     /* rendertarget surface ==> rendertarget surface, scaling */
3253     if(surf_rt32 && surf_rt_dest64) {
3254         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3255         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3256
3257         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3258         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3259     }
3260
3261     /* rendertarget surface ==> texture, scaling (should fail) */
3262     if(surf_rt32 && surf_tex_dest64) {
3263         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3264         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3265     }
3266
3267     /* backbuffer ==> surface tests (no scaling) */
3268     if(backbuffer && surf_tex_rt_dest640_480)
3269     {
3270         RECT src_rect = {0, 0, 640, 480};
3271         RECT src_rect_flipy = {0, 480, 640, 0};
3272         RECT dst_rect = {0, 0, 640, 480};
3273         RECT dst_rect_flipy = {0, 480, 640, 0};
3274
3275         /* Blit with NULL rectangles */
3276         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3277         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3278
3279         /* Blit without scaling */
3280         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3281         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3282
3283         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3284         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3285         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3286
3287         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3288         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3289         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3290     }
3291
3292     /* TODO: Test format conversions */
3293
3294
3295 out:
3296     /* Clean up */
3297     if (backbuffer)
3298         IDirect3DSurface9_Release(backbuffer);
3299     if (surf_rt32)
3300         IDirect3DSurface9_Release(surf_rt32);
3301     if (surf_rt64)
3302         IDirect3DSurface9_Release(surf_rt64);
3303     if (surf_rt_dest64)
3304         IDirect3DSurface9_Release(surf_rt_dest64);
3305     if (surf_temp32)
3306         IDirect3DSurface9_Release(surf_temp32);
3307     if (surf_temp64)
3308         IDirect3DSurface9_Release(surf_temp64);
3309     if (surf_offscreen32)
3310         IDirect3DSurface9_Release(surf_offscreen32);
3311     if (surf_offscreen64)
3312         IDirect3DSurface9_Release(surf_offscreen64);
3313     if (surf_offscreen_dest64)
3314         IDirect3DSurface9_Release(surf_offscreen_dest64);
3315
3316     if (tex_rt32) {
3317         if (surf_tex_rt32)
3318             IDirect3DSurface9_Release(surf_tex_rt32);
3319         IDirect3DTexture9_Release(tex_rt32);
3320     }
3321     if (tex_rt64) {
3322         if (surf_tex_rt64)
3323             IDirect3DSurface9_Release(surf_tex_rt64);
3324         IDirect3DTexture9_Release(tex_rt64);
3325     }
3326     if (tex_rt_dest64) {
3327         if (surf_tex_rt_dest64)
3328             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3329         IDirect3DTexture9_Release(tex_rt_dest64);
3330     }
3331     if (tex_rt_dest640_480) {
3332         if (surf_tex_rt_dest640_480)
3333             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3334         IDirect3DTexture9_Release(tex_rt_dest640_480);
3335     }
3336     if (tex32) {
3337         if (surf_tex32)
3338             IDirect3DSurface9_Release(surf_tex32);
3339         IDirect3DTexture9_Release(tex32);
3340     }
3341     if (tex64) {
3342         if (surf_tex64)
3343             IDirect3DSurface9_Release(surf_tex64);
3344         IDirect3DTexture9_Release(tex64);
3345     }
3346     if (tex_dest64) {
3347         if (surf_tex_dest64)
3348             IDirect3DSurface9_Release(surf_tex_dest64);
3349         IDirect3DTexture9_Release(tex_dest64);
3350     }
3351
3352     if (orig_rt) {
3353         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3354         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3355         IDirect3DSurface9_Release(orig_rt);
3356     }
3357 }
3358
3359 static void maxmip_test(IDirect3DDevice9 *device)
3360 {
3361     IDirect3DTexture9 *texture = NULL;
3362     IDirect3DSurface9 *surface = NULL;
3363     HRESULT hr;
3364     DWORD color;
3365     static const struct
3366     {
3367         struct
3368         {
3369             float x, y, z;
3370             float s, t;
3371         }
3372         v[4];
3373     }
3374     quads[] =
3375     {
3376         {{
3377             {-1.0, -1.0,  0.0,  0.0,  0.0},
3378             {-1.0,  0.0,  0.0,  0.0,  1.0},
3379             { 0.0, -1.0,  0.0,  1.0,  0.0},
3380             { 0.0,  0.0,  0.0,  1.0,  1.0},
3381         }},
3382         {{
3383             { 0.0, -1.0,  0.0,  0.0,  0.0},
3384             { 0.0,  0.0,  0.0,  0.0,  1.0},
3385             { 1.0, -1.0,  0.0,  1.0,  0.0},
3386             { 1.0,  0.0,  0.0,  1.0,  1.0},
3387         }},
3388         {{
3389             { 0.0,  0.0,  0.0,  0.0,  0.0},
3390             { 0.0,  1.0,  0.0,  0.0,  1.0},
3391             { 1.0,  0.0,  0.0,  1.0,  0.0},
3392             { 1.0,  1.0,  0.0,  1.0,  1.0},
3393         }},
3394         {{
3395             {-1.0,  0.0,  0.0,  0.0,  0.0},
3396             {-1.0,  1.0,  0.0,  0.0,  1.0},
3397             { 0.0,  0.0,  0.0,  1.0,  0.0},
3398             { 0.0,  1.0,  0.0,  1.0,  1.0},
3399         }},
3400     };
3401
3402     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3403                                         &texture, NULL);
3404     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3405     if(!texture)
3406     {
3407         skip("Failed to create test texture\n");
3408         return;
3409     }
3410
3411     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3412     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3413     fill_surface(surface, 0xffff0000);
3414     IDirect3DSurface9_Release(surface);
3415     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3416     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3417     fill_surface(surface, 0xff00ff00);
3418     IDirect3DSurface9_Release(surface);
3419     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3420     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3421     fill_surface(surface, 0xff0000ff);
3422     IDirect3DSurface9_Release(surface);
3423
3424     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3425     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3426     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3427     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3428
3429     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3430     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3431
3432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3434
3435     hr = IDirect3DDevice9_BeginScene(device);
3436     if(SUCCEEDED(hr))
3437     {
3438         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3439         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3441         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3442
3443         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3444         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3446         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3447
3448         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3449         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3451         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452
3453         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3454         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3456         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3457         hr = IDirect3DDevice9_EndScene(device);
3458         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3459     }
3460
3461     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3462     color = getPixelColor(device, 160, 360);
3463     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3464     color = getPixelColor(device, 480, 360);
3465     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3466     color = getPixelColor(device, 480, 120);
3467     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3468     color = getPixelColor(device, 160, 120);
3469     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3470     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3471     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3472
3473     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3474     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475
3476     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3478
3479     hr = IDirect3DDevice9_BeginScene(device);
3480     if(SUCCEEDED(hr))
3481     {
3482         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3483         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3485         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3486
3487         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3488         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3490         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3491
3492         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3493         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3495         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3496
3497         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3499         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3500         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3501         hr = IDirect3DDevice9_EndScene(device);
3502         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3503     }
3504
3505     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3506      * level 3 (> levels in texture) samples from the highest level in the
3507      * texture (level 2). */
3508     color = getPixelColor(device, 160, 360);
3509     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3510     color = getPixelColor(device, 480, 360);
3511     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3512     color = getPixelColor(device, 480, 120);
3513     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3514     color = getPixelColor(device, 160, 120);
3515     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3516     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3517     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3518
3519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3521
3522     hr = IDirect3DDevice9_BeginScene(device);
3523     if(SUCCEEDED(hr))
3524     {
3525         DWORD ret;
3526
3527         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3528         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3530         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3531         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3532         ret = IDirect3DTexture9_SetLOD(texture, 1);
3533         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3535         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3536
3537         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3538         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3539         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3540         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3541         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3542         ret = IDirect3DTexture9_SetLOD(texture, 2);
3543         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3545         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3546
3547         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3548         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3549         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3550         ret = IDirect3DTexture9_SetLOD(texture, 1);
3551         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3553         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3554
3555         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3556         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3557         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3558         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3560         ret = IDirect3DTexture9_SetLOD(texture, 1);
3561         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3563         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3564         hr = IDirect3DDevice9_EndScene(device);
3565         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3566     }
3567
3568     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3569      * level 3 (> levels in texture) samples from the highest level in the
3570      * texture (level 2). */
3571     color = getPixelColor(device, 160, 360);
3572     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3573     color = getPixelColor(device, 480, 360);
3574     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3575     color = getPixelColor(device, 480, 120);
3576     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3577     color = getPixelColor(device, 160, 120);
3578     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3579
3580     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3581     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3582
3583     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3585     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3587     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3588     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3589     IDirect3DTexture9_Release(texture);
3590 }
3591
3592 static void release_buffer_test(IDirect3DDevice9 *device)
3593 {
3594     IDirect3DVertexBuffer9 *vb = NULL;
3595     IDirect3DIndexBuffer9 *ib = NULL;
3596     HRESULT hr;
3597     BYTE *data;
3598     LONG ref;
3599
3600     static const struct vertex quad[] = {
3601         {-1.0,      -1.0,       0.1,        0xffff0000},
3602         {-1.0,       1.0,       0.1,        0xffff0000},
3603         { 1.0,       1.0,       0.1,        0xffff0000},
3604
3605         {-1.0,      -1.0,       0.1,        0xff00ff00},
3606         {-1.0,       1.0,       0.1,        0xff00ff00},
3607         { 1.0,       1.0,       0.1,        0xff00ff00}
3608     };
3609     short indices[] = {3, 4, 5};
3610
3611     /* Index and vertex buffers should always be creatable */
3612     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3613                                               D3DPOOL_MANAGED, &vb, NULL);
3614     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3615     if(!vb) {
3616         skip("Failed to create a vertex buffer\n");
3617         return;
3618     }
3619     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3621     if(!ib) {
3622         skip("Failed to create an index buffer\n");
3623         return;
3624     }
3625
3626     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3627     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3628     memcpy(data, quad, sizeof(quad));
3629     hr = IDirect3DVertexBuffer9_Unlock(vb);
3630     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3631
3632     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3633     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3634     memcpy(data, indices, sizeof(indices));
3635     hr = IDirect3DIndexBuffer9_Unlock(ib);
3636     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_SetIndices(device, ib);
3639     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3640     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3641     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3642     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3644
3645     /* Now destroy the bound index buffer and draw again */
3646     ref = IDirect3DIndexBuffer9_Release(ib);
3647     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3648
3649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3651
3652     hr = IDirect3DDevice9_BeginScene(device);
3653     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3654     if(SUCCEEDED(hr))
3655     {
3656         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3657          * making assumptions about the indices or vertices
3658          */
3659         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3661         hr = IDirect3DDevice9_EndScene(device);
3662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3663     }
3664
3665     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3667
3668     hr = IDirect3DDevice9_SetIndices(device, NULL);
3669     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3670     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3671     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3672
3673     /* Index buffer was already destroyed as part of the test */
3674     IDirect3DVertexBuffer9_Release(vb);
3675 }
3676
3677 static void float_texture_test(IDirect3DDevice9 *device)
3678 {
3679     IDirect3D9 *d3d = NULL;
3680     HRESULT hr;
3681     IDirect3DTexture9 *texture = NULL;
3682     D3DLOCKED_RECT lr;
3683     float *data;
3684     DWORD color;
3685     float quad[] = {
3686         -1.0,      -1.0,       0.1,     0.0,    0.0,
3687         -1.0,       1.0,       0.1,     0.0,    1.0,
3688          1.0,      -1.0,       0.1,     1.0,    0.0,
3689          1.0,       1.0,       0.1,     1.0,    1.0,
3690     };
3691
3692     memset(&lr, 0, sizeof(lr));
3693     IDirect3DDevice9_GetDirect3D(device, &d3d);
3694     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3695                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3696         skip("D3DFMT_R32F textures not supported\n");
3697         goto out;
3698     }
3699
3700     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3701                                         D3DPOOL_MANAGED, &texture, NULL);
3702     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3703     if(!texture) {
3704         skip("Failed to create R32F texture\n");
3705         goto out;
3706     }
3707
3708     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3709     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3710     data = lr.pBits;
3711     *data = 0.0;
3712     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3713     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3714
3715     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3717
3718     hr = IDirect3DDevice9_BeginScene(device);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3720     if(SUCCEEDED(hr))
3721     {
3722         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3724
3725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3726         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3727
3728         hr = IDirect3DDevice9_EndScene(device);
3729         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3730     }
3731     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3733
3734     color = getPixelColor(device, 240, 320);
3735     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3736
3737     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3739
3740 out:
3741     if(texture) IDirect3DTexture9_Release(texture);
3742     IDirect3D9_Release(d3d);
3743 }
3744
3745 static void g16r16_texture_test(IDirect3DDevice9 *device)
3746 {
3747     IDirect3D9 *d3d = NULL;
3748     HRESULT hr;
3749     IDirect3DTexture9 *texture = NULL;
3750     D3DLOCKED_RECT lr;
3751     DWORD *data;
3752     DWORD color;
3753     float quad[] = {
3754        -1.0,      -1.0,       0.1,     0.0,    0.0,
3755        -1.0,       1.0,       0.1,     0.0,    1.0,
3756         1.0,      -1.0,       0.1,     1.0,    0.0,
3757         1.0,       1.0,       0.1,     1.0,    1.0,
3758     };
3759
3760     memset(&lr, 0, sizeof(lr));
3761     IDirect3DDevice9_GetDirect3D(device, &d3d);
3762     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3763        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3764            skip("D3DFMT_G16R16 textures not supported\n");
3765            goto out;
3766     }
3767
3768     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3769                                         D3DPOOL_MANAGED, &texture, NULL);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3771     if(!texture) {
3772         skip("Failed to create D3DFMT_G16R16 texture\n");
3773         goto out;
3774     }
3775
3776     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3777     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3778     data = lr.pBits;
3779     *data = 0x0f00f000;
3780     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3781     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3782
3783     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3784     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3785
3786     hr = IDirect3DDevice9_BeginScene(device);
3787     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3788     if(SUCCEEDED(hr))
3789     {
3790         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3791         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3792
3793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3794         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3795
3796         hr = IDirect3DDevice9_EndScene(device);
3797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3798     }
3799     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3801
3802     color = getPixelColor(device, 240, 320);
3803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3804        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3805
3806     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3808
3809 out:
3810     if(texture) IDirect3DTexture9_Release(texture);
3811     IDirect3D9_Release(d3d);
3812 }
3813
3814 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3815 {
3816     LONG x_coords[2][2] =
3817     {
3818         {r.left - 1, r.left + 1},
3819         {r.right + 1, r.right - 1},
3820     };
3821     LONG y_coords[2][2] =
3822     {
3823         {r.top - 1, r.top + 1},
3824         {r.bottom + 1, r.bottom - 1}
3825     };
3826     unsigned int i, j, x_side, y_side;
3827
3828     for (i = 0; i < 2; ++i)
3829     {
3830         for (j = 0; j < 2; ++j)
3831         {
3832             for (x_side = 0; x_side < 2; ++x_side)
3833             {
3834                 for (y_side = 0; y_side < 2; ++y_side)
3835                 {
3836                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3837                     DWORD color;
3838                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3839
3840                     color = getPixelColor(device, x, y);
3841                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3842                             message, x, y, color, expected);
3843                 }
3844             }
3845         }
3846     }
3847 }
3848
3849 struct projected_textures_test_run
3850 {
3851     const char *message;
3852     DWORD flags;
3853     IDirect3DVertexDeclaration9 *decl;
3854     BOOL vs, ps;
3855     RECT rect;
3856 };
3857
3858 static void projected_textures_test(IDirect3DDevice9 *device,
3859         struct projected_textures_test_run tests[4])
3860 {
3861     unsigned int i;
3862
3863     static const DWORD vertex_shader[] =
3864     {
3865         0xfffe0101,                                     /* vs_1_1           */
3866         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3867         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3868         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3869         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3870         0x0000ffff                                      /* end              */
3871     };
3872     static const DWORD pixel_shader[] =
3873     {
3874         0xffff0103,                                     /* ps_1_3           */
3875         0x00000042, 0xb00f0000,                         /* tex t0           */
3876         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3877         0x0000ffff                                      /* end              */
3878     };
3879     IDirect3DVertexShader9 *vs = NULL;
3880     IDirect3DPixelShader9 *ps = NULL;
3881     HRESULT hr;
3882
3883     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3884     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3885     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3886     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3887
3888     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3890
3891     hr = IDirect3DDevice9_BeginScene(device);
3892     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3893     if (FAILED(hr))
3894         return;
3895
3896     for (i = 0; i < 4; ++i)
3897     {
3898         DWORD value = 0xdeadbeef;
3899         static const float proj_quads[] =
3900         {
3901             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3902              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3903             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3904              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3905
3906              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3907              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3908              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3909              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3910
3911             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3912              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3913             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3914              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3915
3916              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3917              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3918              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3919              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3920         };
3921
3922         if (tests[i].vs)
3923             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3924         else
3925             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3926         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3927         if (tests[i].ps)
3928             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3929         else
3930             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3931         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3932
3933         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3934         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3935
3936         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3937         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3938         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3939         ok(SUCCEEDED(hr) && value == tests[i].flags,
3940                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3941
3942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3943                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3944         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3945     }
3946
3947     hr = IDirect3DDevice9_EndScene(device);
3948     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3949
3950     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3951     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3952     IDirect3DVertexShader9_Release(vs);
3953     IDirect3DPixelShader9_Release(ps);
3954
3955     for (i = 0; i < 4; ++i)
3956         check_rect(device, tests[i].rect, tests[i].message);
3957
3958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3960 }
3961
3962 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3963 {
3964     HRESULT hr;
3965     IDirect3D9 *d3d;
3966     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3967     D3DCAPS9 caps;
3968     IDirect3DTexture9 *texture = NULL;
3969     IDirect3DVolumeTexture9 *volume = NULL;
3970     unsigned int x, y, z;
3971     D3DLOCKED_RECT lr;
3972     D3DLOCKED_BOX lb;
3973     DWORD color;
3974     UINT w, h;
3975     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3976     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3977                            0.0, 1.0, 0.0, 0.0,
3978                            0.0, 0.0, 1.0, 0.0,
3979                            0.0, 0.0, 0.0, 1.0};
3980     static const D3DVERTEXELEMENT9 decl_elements[] = {
3981         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3982         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3983         D3DDECL_END()
3984     };
3985     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3986         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3987         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3988         D3DDECL_END()
3989     };
3990     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3991         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3992         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3993         D3DDECL_END()
3994     };
3995     static const D3DVERTEXELEMENT9 decl_elements4[] = {
3996         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3997         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3998         D3DDECL_END()
3999     };
4000     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4001                                                  0x00, 0xff, 0x00, 0x00,
4002                                                  0x00, 0x00, 0x00, 0x00,
4003                                                  0x00, 0x00, 0x00, 0x00};
4004
4005     memset(&lr, 0, sizeof(lr));
4006     memset(&lb, 0, sizeof(lb));
4007     IDirect3DDevice9_GetDirect3D(device, &d3d);
4008     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4009                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4010         fmt = D3DFMT_A16B16G16R16;
4011     }
4012     IDirect3D9_Release(d3d);
4013
4014     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4016     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4017     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4018     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4019     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4020     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4022     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4023     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4024     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4026     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4028     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4030     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4031     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4032     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4033     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4034     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4035     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4038     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4040
4041     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4043     w = min(1024, caps.MaxTextureWidth);
4044     h = min(1024, caps.MaxTextureHeight);
4045     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4046                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4048     if(!texture) {
4049         skip("Failed to create the test texture\n");
4050         return;
4051     }
4052
4053     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4054      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4055      * 1.0 in red and green for the x and y coords
4056      */
4057     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4058     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4059     for(y = 0; y < h; y++) {
4060         for(x = 0; x < w; x++) {
4061             double r_f = (double) y / (double) h;
4062             double g_f = (double) x / (double) w;
4063             if(fmt == D3DFMT_A16B16G16R16) {
4064                 unsigned short r, g;
4065                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4066                 r = (unsigned short) (r_f * 65536.0);
4067                 g = (unsigned short) (g_f * 65536.0);
4068                 dst[0] = r;
4069                 dst[1] = g;
4070                 dst[2] = 0;
4071                 dst[3] = 65535;
4072             } else {
4073                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4074                 unsigned char r = (unsigned char) (r_f * 255.0);
4075                 unsigned char g = (unsigned char) (g_f * 255.0);
4076                 dst[0] = 0;
4077                 dst[1] = g;
4078                 dst[2] = r;
4079                 dst[3] = 255;
4080             }
4081         }
4082     }
4083     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4084     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4085     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4087
4088     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4089     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4090     hr = IDirect3DDevice9_BeginScene(device);
4091     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4092     if(SUCCEEDED(hr))
4093     {
4094         float quad1[] = {
4095             -1.0,      -1.0,       0.1,     1.0,    1.0,
4096             -1.0,       0.0,       0.1,     1.0,    1.0,
4097              0.0,      -1.0,       0.1,     1.0,    1.0,
4098              0.0,       0.0,       0.1,     1.0,    1.0,
4099         };
4100         float quad2[] = {
4101             -1.0,       0.0,       0.1,     1.0,    1.0,
4102             -1.0,       1.0,       0.1,     1.0,    1.0,
4103              0.0,       0.0,       0.1,     1.0,    1.0,
4104              0.0,       1.0,       0.1,     1.0,    1.0,
4105         };
4106         float quad3[] = {
4107              0.0,       0.0,       0.1,     0.5,    0.5,
4108              0.0,       1.0,       0.1,     0.5,    0.5,
4109              1.0,       0.0,       0.1,     0.5,    0.5,
4110              1.0,       1.0,       0.1,     0.5,    0.5,
4111         };
4112         float quad4[] = {
4113              320,       480,       0.1,     1.0,    0.0,    1.0,
4114              320,       240,       0.1,     1.0,    0.0,    1.0,
4115              640,       480,       0.1,     1.0,    0.0,    1.0,
4116              640,       240,       0.1,     1.0,    0.0,    1.0,
4117         };
4118         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4119                           0.0, 0.0, 0.0, 0.0,
4120                           0.0, 0.0, 0.0, 0.0,
4121                           0.0, 0.0, 0.0, 0.0};
4122
4123         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4124         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4125         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4126         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4127         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4128
4129         /* What happens with transforms enabled? */
4130         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4131         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4133         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4134
4135         /* What happens if 4 coords are used, but only 2 given ?*/
4136         mat[8] = 1.0;
4137         mat[13] = 1.0;
4138         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4139         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4140         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4141         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4142         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4143         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4144
4145         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4146          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4147          * due to the coords in the vertices. (turns out red, indeed)
4148          */
4149         memset(mat, 0, sizeof(mat));
4150         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4151         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4152         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4153         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4154         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4155         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4157         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4158
4159         hr = IDirect3DDevice9_EndScene(device);
4160         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4161     }
4162     color = getPixelColor(device, 160, 360);
4163     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4164     color = getPixelColor(device, 160, 120);
4165     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4166     color = getPixelColor(device, 480, 120);
4167     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4168     color = getPixelColor(device, 480, 360);
4169     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4170     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4172
4173     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4175
4176     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4177     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4178     hr = IDirect3DDevice9_BeginScene(device);
4179     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4180     if(SUCCEEDED(hr))
4181     {
4182         float quad1[] = {
4183             -1.0,      -1.0,       0.1,     0.8,    0.2,
4184             -1.0,       0.0,       0.1,     0.8,    0.2,
4185              0.0,      -1.0,       0.1,     0.8,    0.2,
4186              0.0,       0.0,       0.1,     0.8,    0.2,
4187         };
4188         float quad2[] = {
4189             -1.0,       0.0,       0.1,     0.5,    1.0,
4190             -1.0,       1.0,       0.1,     0.5,    1.0,
4191              0.0,       0.0,       0.1,     0.5,    1.0,
4192              0.0,       1.0,       0.1,     0.5,    1.0,
4193         };
4194         float quad3[] = {
4195              0.0,       0.0,       0.1,     0.5,    1.0,
4196              0.0,       1.0,       0.1,     0.5,    1.0,
4197              1.0,       0.0,       0.1,     0.5,    1.0,
4198              1.0,       1.0,       0.1,     0.5,    1.0,
4199         };
4200         float quad4[] = {
4201              0.0,      -1.0,       0.1,     0.8,    0.2,
4202              0.0,       0.0,       0.1,     0.8,    0.2,
4203              1.0,      -1.0,       0.1,     0.8,    0.2,
4204              1.0,       0.0,       0.1,     0.8,    0.2,
4205         };
4206         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4207                           0.0, 0.0, 0.0, 0.0,
4208                           0.0, 1.0, 0.0, 0.0,
4209                           0.0, 0.0, 0.0, 0.0};
4210
4211         /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4212         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4213         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4214         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4215         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4216
4217         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4218         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4219
4220         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4221          * it behaves like COUNT2 because normal textures require 2 coords. */
4222         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4223         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4226
4227         /* Just to be sure, the same as quad2 above */
4228         memset(mat, 0, sizeof(mat));
4229         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4230         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4231         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4232         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4233         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4234         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4235
4236         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4237          * used? And what happens to the first? */
4238         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4239         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4240         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4241         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4242
4243         hr = IDirect3DDevice9_EndScene(device);
4244         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4245     }
4246     color = getPixelColor(device, 160, 360);
4247     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4248     color = getPixelColor(device, 160, 120);
4249     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4250     color = getPixelColor(device, 480, 120);
4251     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4252        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4253     color = getPixelColor(device, 480, 360);
4254     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4255        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4256     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4257     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4258
4259     IDirect3DTexture9_Release(texture);
4260
4261     /* Test projected textures, without any fancy matrices */
4262     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4264     if (SUCCEEDED(hr))
4265     {
4266         struct projected_textures_test_run projected_tests_1[4] =
4267         {
4268             {
4269                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4270                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4271                 decl3,
4272                 FALSE, TRUE,
4273                 {120, 300, 240, 390},
4274             },
4275             {
4276                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4277                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4278                 decl3,
4279                 FALSE, TRUE,
4280                 {400, 360, 480, 420},
4281             },
4282             /* Try with some invalid values */
4283             {
4284                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4285                 0xffffffff,
4286                 decl3,
4287                 FALSE, TRUE,
4288                 {120, 60, 240, 150}
4289             },
4290             {
4291                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4292                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4293                 decl4,
4294                 FALSE, TRUE,
4295                 {340, 210, 360, 225},
4296             }
4297         };
4298         struct projected_textures_test_run projected_tests_2[4] =
4299         {
4300             {
4301                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4302                 D3DTTFF_PROJECTED,
4303                 decl3,
4304                 FALSE, TRUE,
4305                 {120, 300, 240, 390},
4306             },
4307             {
4308                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4309                 D3DTTFF_PROJECTED,
4310                 decl,
4311                 FALSE, TRUE,
4312                 {400, 360, 480, 420},
4313             },
4314             {
4315                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4316                 0xffffffff,
4317                 decl,
4318                 FALSE, TRUE,
4319                 {80, 120, 160, 180},
4320             },
4321             {
4322                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4323                 D3DTTFF_COUNT1,
4324                 decl4,
4325                 FALSE, TRUE,
4326                 {340, 210, 360, 225},
4327             }
4328         };
4329         struct projected_textures_test_run projected_tests_3[4] =
4330         {
4331             {
4332                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4333                 D3DTTFF_PROJECTED,
4334                 decl3,
4335                 TRUE, FALSE,
4336                 {120, 300, 240, 390},
4337             },
4338             {
4339                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4340                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4341                 decl3,
4342                 TRUE, TRUE,
4343                 {440, 300, 560, 390},
4344             },
4345             {
4346                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4347                 0xffffffff,
4348                 decl3,
4349                 TRUE, TRUE,
4350                 {120, 60, 240, 150},
4351             },
4352             {
4353                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4354                 D3DTTFF_PROJECTED,
4355                 decl3,
4356                 FALSE, FALSE,
4357                 {440, 60, 560, 150},
4358             },
4359         };
4360
4361         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4362         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4363
4364         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4365         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4366         for(x = 0; x < 4; x++) {
4367             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4368         }
4369         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4370         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4371         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4372         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4373
4374         projected_textures_test(device, projected_tests_1);
4375         projected_textures_test(device, projected_tests_2);
4376         projected_textures_test(device, projected_tests_3);
4377
4378         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4379         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4380         IDirect3DTexture9_Release(texture);
4381     }
4382
4383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4384     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4385     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4386      * Thus watch out if sampling from texels between 0 and 1.
4387      */
4388     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4389     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4390        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4391     if(!volume) {
4392         skip("Failed to create a volume texture\n");
4393         goto out;
4394     }
4395
4396     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4397     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4398     for(z = 0; z < 32; z++) {
4399         for(y = 0; y < 32; y++) {
4400             for(x = 0; x < 32; x++) {
4401                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4402                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4403                 float r_f = (float) x / 31.0;
4404                 float g_f = (float) y / 31.0;
4405                 float b_f = (float) z / 31.0;
4406
4407                 if(fmt == D3DFMT_A16B16G16R16) {
4408                     unsigned short *mem_s = mem;
4409                     mem_s[0]  = r_f * 65535.0;
4410                     mem_s[1]  = g_f * 65535.0;
4411                     mem_s[2]  = b_f * 65535.0;
4412                     mem_s[3]  = 65535;
4413                 } else {
4414                     unsigned char *mem_c = mem;
4415                     mem_c[0]  = b_f * 255.0;
4416                     mem_c[1]  = g_f * 255.0;
4417                     mem_c[2]  = r_f * 255.0;
4418                     mem_c[3]  = 255;
4419                 }
4420             }
4421         }
4422     }
4423     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4424     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4425
4426     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4427     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4428
4429     hr = IDirect3DDevice9_BeginScene(device);
4430     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4431     if(SUCCEEDED(hr))
4432     {
4433         float quad1[] = {
4434             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4435             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4436              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4437              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4438         };
4439         float quad2[] = {
4440             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4441             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4442              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4443              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4444         };
4445         float quad3[] = {
4446              0.0,       0.0,       0.1,     0.0,    0.0,
4447              0.0,       1.0,       0.1,     0.0,    0.0,
4448              1.0,       0.0,       0.1,     0.0,    0.0,
4449              1.0,       1.0,       0.1,     0.0,    0.0
4450         };
4451         float quad4[] = {
4452              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4453              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4454              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4455              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4456         };
4457         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4458                          0.0, 0.0, 1.0, 0.0,
4459                          0.0, 1.0, 0.0, 0.0,
4460                          0.0, 0.0, 0.0, 1.0};
4461         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4462         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4463
4464         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4465          * values
4466          */
4467         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4468         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4469         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4470         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4471         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4472         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4473
4474         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4475          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4476          * otherwise the w will be missing(blue).
4477          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4478          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4479         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4480         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4482         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4483
4484         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4485         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4486         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4487         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4488         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4489         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4490         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4492         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4493
4494         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4495          * disable. ATI extends it up to the amount of values needed for the volume texture
4496          */
4497         memset(mat, 0, sizeof(mat));
4498         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4499         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4500         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4501         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4502         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4503         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4504         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4505         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4506
4507         hr = IDirect3DDevice9_EndScene(device);
4508         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4509     }
4510
4511     color = getPixelColor(device, 160, 360);
4512     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4513     color = getPixelColor(device, 160, 120);
4514     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4515        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4516     color = getPixelColor(device, 480, 120);
4517     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4518     color = getPixelColor(device, 480, 360);
4519     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4520
4521     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4522     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4523
4524     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4525     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4526     hr = IDirect3DDevice9_BeginScene(device);
4527     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4528     if(SUCCEEDED(hr))
4529     {
4530         float quad1[] = {
4531             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4532             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4533              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4534              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4535         };
4536         float quad2[] = {
4537             -1.0,       0.0,       0.1,
4538             -1.0,       1.0,       0.1,
4539              0.0,       0.0,       0.1,
4540              0.0,       1.0,       0.1,
4541         };
4542         float quad3[] = {
4543              0.0,       0.0,       0.1,     1.0,
4544              0.0,       1.0,       0.1,     1.0,
4545              1.0,       0.0,       0.1,     1.0,
4546              1.0,       1.0,       0.1,     1.0
4547         };
4548         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4549                            0.0, 0.0, 0.0, 0.0,
4550                            0.0, 0.0, 0.0, 0.0,
4551                            0.0, 1.0, 0.0, 0.0};
4552         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4553                            1.0, 0.0, 0.0, 0.0,
4554                            0.0, 1.0, 0.0, 0.0,
4555                            0.0, 0.0, 1.0, 0.0};
4556         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4558
4559         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4560          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4561          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4562          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4563          * 4th *input* coordinate.
4564          */
4565         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4566         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4567         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4568         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4570         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4571
4572         /* None passed */
4573         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4574         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4575         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4576         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4577         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4578         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4579
4580         /* 4 used, 1 passed */
4581         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4582         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4583         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4585         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4586         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4587
4588         hr = IDirect3DDevice9_EndScene(device);
4589         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4590     }
4591     color = getPixelColor(device, 160, 360);
4592     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4593     color = getPixelColor(device, 160, 120);
4594     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4595     color = getPixelColor(device, 480, 120);
4596     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4597     /* Quad4: unused */
4598
4599     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4600     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4601
4602     IDirect3DVolumeTexture9_Release(volume);
4603
4604     out:
4605     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4606     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4607     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4608     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4609     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4610     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4611     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4612     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4613     IDirect3DVertexDeclaration9_Release(decl);
4614     IDirect3DVertexDeclaration9_Release(decl2);
4615     IDirect3DVertexDeclaration9_Release(decl3);
4616     IDirect3DVertexDeclaration9_Release(decl4);
4617 }
4618
4619 static void texdepth_test(IDirect3DDevice9 *device)
4620 {
4621     IDirect3DPixelShader9 *shader;
4622     HRESULT hr;
4623     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4624     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4625     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4626     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4627     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4628     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4629     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4630     DWORD shader_code[] = {
4631         0xffff0104,                                                                 /* ps_1_4               */
4632         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4633         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4634         0x0000fffd,                                                                 /* phase                */
4635         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4636         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4637         0x0000ffff                                                                  /* end                  */
4638     };
4639     DWORD color;
4640     float vertex[] = {
4641        -1.0,   -1.0,    0.0,
4642         1.0,   -1.0,    1.0,
4643        -1.0,    1.0,    0.0,
4644         1.0,    1.0,    1.0
4645     };
4646
4647     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4649
4650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4653     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4657     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4658     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4660
4661     /* Fill the depth buffer with a gradient */
4662     hr = IDirect3DDevice9_BeginScene(device);
4663     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4664     if(SUCCEEDED(hr))
4665     {
4666         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4667         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4668         hr = IDirect3DDevice9_EndScene(device);
4669         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4670     }
4671
4672     /* Now perform the actual tests. Same geometry, but with the shader */
4673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4675     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4676     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4677     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4678     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4679
4680     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4681     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4682     hr = IDirect3DDevice9_BeginScene(device);
4683     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4684     if(SUCCEEDED(hr))
4685     {
4686         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4687         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4688
4689         hr = IDirect3DDevice9_EndScene(device);
4690         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4691     }
4692
4693     color = getPixelColor(device, 158, 240);
4694     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4695     color = getPixelColor(device, 162, 240);
4696     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4697
4698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4699     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4700
4701     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4702     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4703
4704     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4705     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4706     hr = IDirect3DDevice9_BeginScene(device);
4707     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4708     if(SUCCEEDED(hr))
4709     {
4710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4711         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4712
4713         hr = IDirect3DDevice9_EndScene(device);
4714         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4715     }
4716
4717     color = getPixelColor(device, 318, 240);
4718     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4719     color = getPixelColor(device, 322, 240);
4720     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4721
4722     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4723     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4724
4725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4726     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4727
4728     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4729     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4730     hr = IDirect3DDevice9_BeginScene(device);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4732     if(SUCCEEDED(hr))
4733     {
4734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4735         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4736
4737         hr = IDirect3DDevice9_EndScene(device);
4738         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4739     }
4740
4741     color = getPixelColor(device, 1, 240);
4742     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4743
4744     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4748     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4749
4750     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4752     hr = IDirect3DDevice9_BeginScene(device);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4754     if(SUCCEEDED(hr))
4755     {
4756         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4757         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4758
4759         hr = IDirect3DDevice9_EndScene(device);
4760         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4761     }
4762     color = getPixelColor(device, 318, 240);
4763     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4764     color = getPixelColor(device, 322, 240);
4765     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4766
4767     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4769
4770     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4771     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4772
4773     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4774     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4775     hr = IDirect3DDevice9_BeginScene(device);
4776     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4777     if(SUCCEEDED(hr))
4778     {
4779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781
4782         hr = IDirect3DDevice9_EndScene(device);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4784     }
4785
4786     color = getPixelColor(device, 1, 240);
4787     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4788
4789     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4790     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4791
4792     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4793     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4794
4795     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4797     hr = IDirect3DDevice9_BeginScene(device);
4798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4799     if(SUCCEEDED(hr))
4800     {
4801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4803
4804         hr = IDirect3DDevice9_EndScene(device);
4805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4806     }
4807
4808     color = getPixelColor(device, 638, 240);
4809     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4810
4811     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4813
4814     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4815     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4816
4817     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4818     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4819     hr = IDirect3DDevice9_BeginScene(device);
4820     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4821     if(SUCCEEDED(hr))
4822     {
4823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4824         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4825
4826         hr = IDirect3DDevice9_EndScene(device);
4827         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4828     }
4829
4830     color = getPixelColor(device, 638, 240);
4831     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4832
4833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4834     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4835
4836     /* Cleanup */
4837     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4839     IDirect3DPixelShader9_Release(shader);
4840
4841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4842     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4844     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4845 }
4846
4847 static void texkill_test(IDirect3DDevice9 *device)
4848 {
4849     IDirect3DPixelShader9 *shader;
4850     HRESULT hr;
4851     DWORD color;
4852
4853     const float vertex[] = {
4854     /*                          bottom  top    right    left */
4855         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4856          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4857         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4858          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4859     };
4860
4861     DWORD shader_code_11[] = {
4862     0xffff0101,                                                             /* ps_1_1                     */
4863     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4864     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4865     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4866     0x0000ffff                                                              /* end                        */
4867     };
4868     DWORD shader_code_20[] = {
4869     0xffff0200,                                                             /* ps_2_0                     */
4870     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4871     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4872     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4873     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4874     0x0000ffff                                                              /* end                        */
4875     };
4876
4877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4879     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4880     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4881
4882     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4883     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884     hr = IDirect3DDevice9_BeginScene(device);
4885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4886     if(SUCCEEDED(hr))
4887     {
4888         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4889         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4891         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4892         hr = IDirect3DDevice9_EndScene(device);
4893         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4894     }
4895     color = getPixelColor(device, 63, 46);
4896     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4897     color = getPixelColor(device, 66, 46);
4898     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4899     color = getPixelColor(device, 63, 49);
4900     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4901     color = getPixelColor(device, 66, 49);
4902     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4903
4904     color = getPixelColor(device, 578, 46);
4905     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4906     color = getPixelColor(device, 575, 46);
4907     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4908     color = getPixelColor(device, 578, 49);
4909     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4910     color = getPixelColor(device, 575, 49);
4911     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4912
4913     color = getPixelColor(device, 63, 430);
4914     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4915     color = getPixelColor(device, 63, 433);
4916     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4917     color = getPixelColor(device, 66, 433);
4918     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4919     color = getPixelColor(device, 66, 430);
4920     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4921
4922     color = getPixelColor(device, 578, 430);
4923     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4924     color = getPixelColor(device, 578, 433);
4925     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4926     color = getPixelColor(device, 575, 433);
4927     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4928     color = getPixelColor(device, 575, 430);
4929     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4930
4931     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4933
4934     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4936     IDirect3DPixelShader9_Release(shader);
4937
4938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4941     if(FAILED(hr)) {
4942         skip("Failed to create 2.0 test shader, most likely not supported\n");
4943         return;
4944     }
4945
4946     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4947     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4948     hr = IDirect3DDevice9_BeginScene(device);
4949     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4950     if(SUCCEEDED(hr))
4951     {
4952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4953         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4954         hr = IDirect3DDevice9_EndScene(device);
4955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4956     }
4957
4958     color = getPixelColor(device, 63, 46);
4959     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4960     color = getPixelColor(device, 66, 46);
4961     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4962     color = getPixelColor(device, 63, 49);
4963     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4964     color = getPixelColor(device, 66, 49);
4965     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4966
4967     color = getPixelColor(device, 578, 46);
4968     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4969     color = getPixelColor(device, 575, 46);
4970     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4971     color = getPixelColor(device, 578, 49);
4972     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4973     color = getPixelColor(device, 575, 49);
4974     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4975
4976     color = getPixelColor(device, 63, 430);
4977     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4978     color = getPixelColor(device, 63, 433);
4979     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4980     color = getPixelColor(device, 66, 433);
4981     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4982     color = getPixelColor(device, 66, 430);
4983     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4984
4985     color = getPixelColor(device, 578, 430);
4986     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4987     color = getPixelColor(device, 578, 433);
4988     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4989     color = getPixelColor(device, 575, 433);
4990     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4991     color = getPixelColor(device, 575, 430);
4992     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4993
4994     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4995     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4996
4997     /* Cleanup */
4998     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5000     IDirect3DPixelShader9_Release(shader);
5001 }
5002
5003 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5004 {
5005     IDirect3D9 *d3d9;
5006     HRESULT hr;
5007     IDirect3DTexture9 *texture;
5008     IDirect3DPixelShader9 *shader;
5009     IDirect3DPixelShader9 *shader2;
5010     D3DLOCKED_RECT lr;
5011     DWORD color;
5012     DWORD shader_code[] = {
5013         0xffff0101,                             /* ps_1_1       */
5014         0x00000042, 0xb00f0000,                 /* tex t0       */
5015         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
5016         0x0000ffff                              /* end          */
5017     };
5018     DWORD shader_code2[] = {
5019         0xffff0101,                             /* ps_1_1       */
5020         0x00000042, 0xb00f0000,                 /* tex t0       */
5021         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
5022         0x0000ffff                              /* end          */
5023     };
5024
5025     float quad[] = {
5026        -1.0,   -1.0,   0.1,     0.5,    0.5,
5027         1.0,   -1.0,   0.1,     0.5,    0.5,
5028        -1.0,    1.0,   0.1,     0.5,    0.5,
5029         1.0,    1.0,   0.1,     0.5,    0.5,
5030     };
5031
5032     memset(&lr, 0, sizeof(lr));
5033     IDirect3DDevice9_GetDirect3D(device, &d3d9);
5034     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5035                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5036     IDirect3D9_Release(d3d9);
5037     if(FAILED(hr)) {
5038         skip("No D3DFMT_X8L8V8U8 support\n");
5039         return;
5040     };
5041
5042     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5043     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5044
5045     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5046     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5047     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5048     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5049     *((DWORD *) lr.pBits) = 0x11ca3141;
5050     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5051     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5052
5053     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5054     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5055     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5056     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5057
5058     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5059     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5060     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5061     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5062     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5064
5065     hr = IDirect3DDevice9_BeginScene(device);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5067     if(SUCCEEDED(hr))
5068     {
5069         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5070         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5071
5072         hr = IDirect3DDevice9_EndScene(device);
5073         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5074     }
5075     color = getPixelColor(device, 578, 430);
5076     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5077        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5078     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5080
5081     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5082     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5083     hr = IDirect3DDevice9_BeginScene(device);
5084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5085     if(SUCCEEDED(hr))
5086     {
5087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5088         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5089
5090         hr = IDirect3DDevice9_EndScene(device);
5091         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5092     }
5093     color = getPixelColor(device, 578, 430);
5094     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5095     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5096     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5097
5098     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5099     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5100     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5101     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5102     IDirect3DPixelShader9_Release(shader);
5103     IDirect3DPixelShader9_Release(shader2);
5104     IDirect3DTexture9_Release(texture);
5105 }
5106
5107 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5108 {
5109     HRESULT hr;
5110     IDirect3D9 *d3d;
5111     IDirect3DTexture9 *texture = NULL;
5112     IDirect3DSurface9 *surface;
5113     DWORD color;
5114     const RECT r1 = {256, 256, 512, 512};
5115     const RECT r2 = {512, 256, 768, 512};
5116     const RECT r3 = {256, 512, 512, 768};
5117     const RECT r4 = {512, 512, 768, 768};
5118     unsigned int x, y;
5119     D3DLOCKED_RECT lr;
5120     memset(&lr, 0, sizeof(lr));
5121
5122     IDirect3DDevice9_GetDirect3D(device, &d3d);
5123     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5124        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5125         skip("No autogenmipmap support\n");
5126         IDirect3D9_Release(d3d);
5127         return;
5128     }
5129     IDirect3D9_Release(d3d);
5130
5131     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5132     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5133
5134     /* Make the mipmap big, so that a smaller mipmap is used
5135      */
5136     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5137                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5138     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5139
5140     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5141     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5142     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5143     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5144     for(y = 0; y < 1024; y++) {
5145         for(x = 0; x < 1024; x++) {
5146             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5147             POINT pt;
5148
5149             pt.x = x;
5150             pt.y = y;
5151             if(PtInRect(&r1, pt)) {
5152                 *dst = 0xffff0000;
5153             } else if(PtInRect(&r2, pt)) {
5154                 *dst = 0xff00ff00;
5155             } else if(PtInRect(&r3, pt)) {
5156                 *dst = 0xff0000ff;
5157             } else if(PtInRect(&r4, pt)) {
5158                 *dst = 0xff000000;
5159             } else {
5160                 *dst = 0xffffffff;
5161             }
5162         }
5163     }
5164     hr = IDirect3DSurface9_UnlockRect(surface);
5165     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5166     IDirect3DSurface9_Release(surface);
5167
5168     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5169     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5170     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5171     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5172
5173     hr = IDirect3DDevice9_BeginScene(device);
5174     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5175     if(SUCCEEDED(hr)) {
5176         const float quad[] =  {
5177            -0.5,   -0.5,    0.1,    0.0,    0.0,
5178            -0.5,    0.5,    0.1,    0.0,    1.0,
5179             0.5,   -0.5,    0.1,    1.0,    0.0,
5180             0.5,    0.5,    0.1,    1.0,    1.0
5181         };
5182
5183         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5184         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5187         hr = IDirect3DDevice9_EndScene(device);
5188         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5189     }
5190     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5191     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5192     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5193     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5194     IDirect3DTexture9_Release(texture);
5195
5196     color = getPixelColor(device, 200, 200);
5197     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5198     color = getPixelColor(device, 280, 200);
5199     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5200     color = getPixelColor(device, 360, 200);
5201     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5202     color = getPixelColor(device, 440, 200);
5203     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5204     color = getPixelColor(device, 200, 270);
5205     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5206     color = getPixelColor(device, 280, 270);
5207     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5208     color = getPixelColor(device, 360, 270);
5209     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5210     color = getPixelColor(device, 440, 270);
5211     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5212     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5213     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5214 }
5215
5216 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5217 {
5218     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5219     IDirect3DVertexDeclaration9 *decl;
5220     HRESULT hr;
5221     DWORD color;
5222     DWORD shader_code_11[] =  {
5223         0xfffe0101,                                         /* vs_1_1           */
5224         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5225         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5226         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5227         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5228         0x0000ffff                                          /* end              */
5229     };
5230     DWORD shader_code_11_2[] =  {
5231         0xfffe0101,                                         /* vs_1_1           */
5232         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5233         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5234         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5235         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5236         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5237         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5238         0x0000ffff                                          /* end              */
5239     };
5240     DWORD shader_code_20[] =  {
5241         0xfffe0200,                                         /* vs_2_0           */
5242         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5243         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5244         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5245         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5246         0x0000ffff                                          /* end              */
5247     };
5248     DWORD shader_code_20_2[] =  {
5249         0xfffe0200,                                         /* vs_2_0           */
5250         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5251         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5252         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5253         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5254         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5255         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5256         0x0000ffff                                          /* end              */
5257     };
5258     static const D3DVERTEXELEMENT9 decl_elements[] = {
5259         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5260         D3DDECL_END()
5261     };
5262     float quad1[] = {
5263         -1.0,   -1.0,   0.1,
5264          0.0,   -1.0,   0.1,
5265         -1.0,    0.0,   0.1,
5266          0.0,    0.0,   0.1
5267     };
5268     float quad2[] = {
5269          0.0,   -1.0,   0.1,
5270          1.0,   -1.0,   0.1,
5271          0.0,    0.0,   0.1,
5272          1.0,    0.0,   0.1
5273     };
5274     float quad3[] = {
5275          0.0,    0.0,   0.1,
5276          1.0,    0.0,   0.1,
5277          0.0,    1.0,   0.1,
5278          1.0,    1.0,   0.1
5279     };
5280     float quad4[] = {
5281         -1.0,    0.0,   0.1,
5282          0.0,    0.0,   0.1,
5283         -1.0,    1.0,   0.1,
5284          0.0,    1.0,   0.1
5285     };
5286     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5287     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5288
5289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5291
5292     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5294     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5295     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5296     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5297     if(FAILED(hr)) shader_20 = NULL;
5298     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5299     if(FAILED(hr)) shader_20_2 = NULL;
5300     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5302
5303     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5304     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5305     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5307     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5308     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5309
5310     hr = IDirect3DDevice9_BeginScene(device);
5311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5312     if(SUCCEEDED(hr))
5313     {
5314         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5315         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5318
5319         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5320         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323
5324         if(shader_20) {
5325             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5326             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5327             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5328             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5329         }
5330
5331         if(shader_20_2) {
5332             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5333             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5334             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5335             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5336         }
5337
5338         hr = IDirect3DDevice9_EndScene(device);
5339         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5340     }
5341
5342     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5343     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5344     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5345     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5346
5347     color = getPixelColor(device, 160, 360);
5348     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5349        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5350     color = getPixelColor(device, 480, 360);
5351     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5352        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5353     if(shader_20) {
5354         color = getPixelColor(device, 480, 120);
5355         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5356            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5357     }
5358     if(shader_20_2) {
5359         color = getPixelColor(device, 160, 120);
5360         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5361            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5362     }
5363     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5364     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5365
5366     IDirect3DVertexDeclaration9_Release(decl);
5367     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5368     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5369     IDirect3DVertexShader9_Release(shader_11_2);
5370     IDirect3DVertexShader9_Release(shader_11);
5371 }
5372
5373 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5374 {
5375     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5376     HRESULT hr;
5377     DWORD color;
5378     DWORD shader_code_11[] =  {
5379         0xffff0101,                                         /* ps_1_1           */
5380         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5381         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5382         0x0000ffff                                          /* end              */
5383     };
5384     DWORD shader_code_12[] =  {
5385         0xffff0102,                                         /* ps_1_2           */
5386         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5387         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5388         0x0000ffff                                          /* end              */
5389     };
5390     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5391      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5392      * During development of this test, 1.3 shaders were verified too
5393      */
5394     DWORD shader_code_14[] =  {
5395         0xffff0104,                                         /* ps_1_4           */
5396         /* Try to make one constant local. It gets clamped too, although the binary contains
5397          * the bigger numbers
5398          */
5399         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5400         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5401         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5402         0x0000ffff                                          /* end              */
5403     };
5404     DWORD shader_code_20[] =  {
5405         0xffff0200,                                         /* ps_2_0           */
5406         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5407         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5408         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5409         0x0000ffff                                          /* end              */
5410     };
5411     float quad1[] = {
5412         -1.0,   -1.0,   0.1,
5413          0.0,   -1.0,   0.1,
5414         -1.0,    0.0,   0.1,
5415          0.0,    0.0,   0.1
5416     };
5417     float quad2[] = {
5418          0.0,   -1.0,   0.1,
5419          1.0,   -1.0,   0.1,
5420          0.0,    0.0,   0.1,
5421          1.0,    0.0,   0.1
5422     };
5423     float quad3[] = {
5424          0.0,    0.0,   0.1,
5425          1.0,    0.0,   0.1,
5426          0.0,    1.0,   0.1,
5427          1.0,    1.0,   0.1
5428     };
5429     float quad4[] = {
5430         -1.0,    0.0,   0.1,
5431          0.0,    0.0,   0.1,
5432         -1.0,    1.0,   0.1,
5433          0.0,    1.0,   0.1
5434     };
5435     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5436     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5437
5438     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5440
5441     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5442     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5443     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5444     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5445     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5446     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5447     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5448     if(FAILED(hr)) shader_20 = NULL;
5449
5450     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5451     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5452     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5453     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5454     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5455     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5456
5457     hr = IDirect3DDevice9_BeginScene(device);
5458     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5459     if(SUCCEEDED(hr))
5460     {
5461         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5462         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5463         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5464         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5465
5466         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5467         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5468         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5469         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5470
5471         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5472         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5473         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5474         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5475
5476         if(shader_20) {
5477             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5478             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5479             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5480             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5481         }
5482
5483         hr = IDirect3DDevice9_EndScene(device);
5484         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5485     }
5486     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5487     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5488
5489     color = getPixelColor(device, 160, 360);
5490     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5491        "quad 1 has color %08x, expected 0x00808000\n", color);
5492     color = getPixelColor(device, 480, 360);
5493     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5494        "quad 2 has color %08x, expected 0x00808000\n", color);
5495     color = getPixelColor(device, 480, 120);
5496     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5497        "quad 3 has color %08x, expected 0x00808000\n", color);
5498     if(shader_20) {
5499         color = getPixelColor(device, 160, 120);
5500         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5501            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5502     }
5503     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5504     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5505
5506     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5507     IDirect3DPixelShader9_Release(shader_14);
5508     IDirect3DPixelShader9_Release(shader_12);
5509     IDirect3DPixelShader9_Release(shader_11);
5510 }
5511
5512 static void dp2add_ps_test(IDirect3DDevice9 *device)
5513 {
5514     IDirect3DPixelShader9 *shader_dp2add = NULL;
5515     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5516     HRESULT hr;
5517     DWORD color;
5518
5519     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5520      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5521      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5522      * r0 first.
5523      * The result here for the r,g,b components should be roughly 0.5:
5524      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5525     static const DWORD shader_code_dp2add[] =  {
5526         0xffff0200,                                                             /* ps_2_0                       */
5527         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5528
5529         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5530         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5531
5532         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5533         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5534         0x0000ffff                                                              /* end                          */
5535     };
5536
5537     /* Test the _sat modifier, too.  Result here should be:
5538      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5539      *      _SAT: ==> 1.0
5540      *   ADD: (1.0 + -0.5) = 0.5
5541      */
5542     static const DWORD shader_code_dp2add_sat[] =  {
5543         0xffff0200,                                                             /* ps_2_0                           */
5544         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5545
5546         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5547         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5548         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5549
5550         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5551         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5552         0x0000ffff                                                              /* end                              */
5553     };
5554
5555     const float quad[] = {
5556         -1.0,   -1.0,   0.1,
5557          1.0,   -1.0,   0.1,
5558         -1.0,    1.0,   0.1,
5559          1.0,    1.0,   0.1
5560     };
5561
5562
5563     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5564     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5565
5566     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5567     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5568
5569     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5570     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5571
5572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5574
5575     if (shader_dp2add) {
5576
5577         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5578         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5579
5580         hr = IDirect3DDevice9_BeginScene(device);
5581         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5582         if(SUCCEEDED(hr))
5583         {
5584             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5585             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5586
5587             hr = IDirect3DDevice9_EndScene(device);
5588             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5589         }
5590
5591         color = getPixelColor(device, 360, 240);
5592         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5593                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5594
5595         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5596         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5597
5598         IDirect3DPixelShader9_Release(shader_dp2add);
5599     } else {
5600         skip("dp2add shader creation failed\n");
5601     }
5602
5603     if (shader_dp2add_sat) {
5604
5605         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5606         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5607
5608         hr = IDirect3DDevice9_BeginScene(device);
5609         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5610         if(SUCCEEDED(hr))
5611         {
5612             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5613             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5614
5615             hr = IDirect3DDevice9_EndScene(device);
5616             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5617         }
5618
5619         color = getPixelColor(device, 360, 240);
5620         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5621                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5622
5623         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5625
5626         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5627     } else {
5628         skip("dp2add shader creation failed\n");
5629     }
5630
5631     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5632     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5633 }
5634
5635 static void cnd_test(IDirect3DDevice9 *device)
5636 {
5637     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5638     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5639     HRESULT hr;
5640     DWORD color;
5641     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5642      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5643      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5644      */
5645     DWORD shader_code_11[] =  {
5646         0xffff0101,                                                                 /* ps_1_1               */
5647         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5648         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5649         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5650         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5651         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5652         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5653         0x0000ffff                                                                  /* end                  */
5654     };
5655     DWORD shader_code_12[] =  {
5656         0xffff0102,                                                                 /* ps_1_2               */
5657         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5658         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5659         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5660         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5661         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5662         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5663         0x0000ffff                                                                  /* end                  */
5664     };
5665     DWORD shader_code_13[] =  {
5666         0xffff0103,                                                                 /* ps_1_3               */
5667         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5668         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5669         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5670         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5671         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5672         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5673         0x0000ffff                                                                  /* end                  */
5674     };
5675     DWORD shader_code_14[] =  {
5676         0xffff0104,                                                                 /* ps_1_3               */
5677         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5678         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5679         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5680         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5681         0x0000ffff                                                                  /* end                  */
5682     };
5683
5684     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5685      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5686      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5687      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5688      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5689      * well enough.
5690      *
5691      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5692      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5693      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5694      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5695      */
5696     DWORD shader_code_11_coissue[] =  {
5697         0xffff0101,                                                             /* ps_1_1                   */
5698         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5699         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5700         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5701         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5702         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5703         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5704         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5705         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5706         /* 0x40000000 = D3DSI_COISSUE */
5707         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5708         0x0000ffff                                                              /* end                      */
5709     };
5710     DWORD shader_code_12_coissue[] =  {
5711         0xffff0102,                                                             /* ps_1_2                   */
5712         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5713         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5714         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5715         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5716         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5717         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5718         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5719         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5720         /* 0x40000000 = D3DSI_COISSUE */
5721         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5722         0x0000ffff                                                              /* end                      */
5723     };
5724     DWORD shader_code_13_coissue[] =  {
5725         0xffff0103,                                                             /* ps_1_3                   */
5726         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5727         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5728         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5729         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5730         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5731         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5732         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5733         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5734         /* 0x40000000 = D3DSI_COISSUE */
5735         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5736         0x0000ffff                                                              /* end                      */
5737     };
5738     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5739      * compare against 0.5
5740      */
5741     DWORD shader_code_14_coissue[] =  {
5742         0xffff0104,                                                             /* ps_1_4                   */
5743         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5744         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5745         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5746         /* 0x40000000 = D3DSI_COISSUE */
5747         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5748         0x0000ffff                                                              /* end                      */
5749     };
5750     float quad1[] = {
5751         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5752          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5753         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5754          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5755     };
5756     float quad2[] = {
5757          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5758          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5759          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5760          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5761     };
5762     float quad3[] = {
5763          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5764          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5765          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5766          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5767     };
5768     float quad4[] = {
5769         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5770          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5771         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5772          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5773     };
5774     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5775     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5776     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5777     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5778
5779     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5780     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5781
5782     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5783     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5784     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5785     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5786     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5787     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5788     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5789     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5790     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5791     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5792     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5793     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5794     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5795     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5796     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5797     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5798
5799     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5800     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5801     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5802     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5803     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5804     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5805
5806     hr = IDirect3DDevice9_BeginScene(device);
5807     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5808     if(SUCCEEDED(hr))
5809     {
5810         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5811         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5812         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5813         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5814
5815         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5816         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5818         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5819
5820         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5821         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5822         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5823         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5824
5825         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5826         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5827         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5828         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5829
5830         hr = IDirect3DDevice9_EndScene(device);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5832     }
5833
5834     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5835     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5836
5837     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5838     color = getPixelColor(device, 158, 118);
5839     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5840     color = getPixelColor(device, 162, 118);
5841     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5842     color = getPixelColor(device, 158, 122);
5843     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5844     color = getPixelColor(device, 162, 122);
5845     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5846
5847     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5848     color = getPixelColor(device, 158, 358);
5849     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5850     color = getPixelColor(device, 162, 358);
5851     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5852         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5853     color = getPixelColor(device, 158, 362);
5854     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5855     color = getPixelColor(device, 162, 362);
5856     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5857         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5858
5859     /* 1.2 shader */
5860     color = getPixelColor(device, 478, 358);
5861     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5862     color = getPixelColor(device, 482, 358);
5863     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5864         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5865     color = getPixelColor(device, 478, 362);
5866     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5867     color = getPixelColor(device, 482, 362);
5868     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5869         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5870
5871     /* 1.3 shader */
5872     color = getPixelColor(device, 478, 118);
5873     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5874     color = getPixelColor(device, 482, 118);
5875     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5876         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5877     color = getPixelColor(device, 478, 122);
5878     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5879     color = getPixelColor(device, 482, 122);
5880     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5881         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5882
5883     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5884     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5885
5886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5887     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5888     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5889     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5890     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5891     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5892
5893     hr = IDirect3DDevice9_BeginScene(device);
5894     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5895     if(SUCCEEDED(hr))
5896     {
5897         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5898         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5899         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5900         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5901
5902         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5903         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5904         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5905         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5906
5907         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5908         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5910         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5911
5912         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5913         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5915         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5916
5917         hr = IDirect3DDevice9_EndScene(device);
5918         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5919     }
5920
5921     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5922     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5923
5924     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5925      * that we swapped the values in c1 and c2 to make the other tests return some color
5926      */
5927     color = getPixelColor(device, 158, 118);
5928     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5929     color = getPixelColor(device, 162, 118);
5930     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5931     color = getPixelColor(device, 158, 122);
5932     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5933     color = getPixelColor(device, 162, 122);
5934     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5935
5936     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5937      * (The Win7 nvidia driver always selects c2)
5938      */
5939     color = getPixelColor(device, 158, 358);
5940     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5941         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5942     color = getPixelColor(device, 162, 358);
5943     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5944         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5945     color = getPixelColor(device, 158, 362);
5946     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5947         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5948     color = getPixelColor(device, 162, 362);
5949     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5950         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5951
5952     /* 1.2 shader */
5953     color = getPixelColor(device, 478, 358);
5954     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5955         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5956     color = getPixelColor(device, 482, 358);
5957     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5958         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5959     color = getPixelColor(device, 478, 362);
5960     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5961         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5962     color = getPixelColor(device, 482, 362);
5963     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5964         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5965
5966     /* 1.3 shader */
5967     color = getPixelColor(device, 478, 118);
5968     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5969         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5970     color = getPixelColor(device, 482, 118);
5971     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5972         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5973     color = getPixelColor(device, 478, 122);
5974     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5975         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5976     color = getPixelColor(device, 482, 122);
5977     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5978         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5979
5980     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5981     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5982
5983     IDirect3DPixelShader9_Release(shader_14_coissue);
5984     IDirect3DPixelShader9_Release(shader_13_coissue);
5985     IDirect3DPixelShader9_Release(shader_12_coissue);
5986     IDirect3DPixelShader9_Release(shader_11_coissue);
5987     IDirect3DPixelShader9_Release(shader_14);
5988     IDirect3DPixelShader9_Release(shader_13);
5989     IDirect3DPixelShader9_Release(shader_12);
5990     IDirect3DPixelShader9_Release(shader_11);
5991 }
5992
5993 static void nested_loop_test(IDirect3DDevice9 *device) {
5994     const DWORD shader_code[] = {
5995         0xffff0300,                                                             /* ps_3_0               */
5996         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5997         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5998         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5999         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
6000         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6001         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6002         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
6003         0x0000001d,                                                             /* endloop              */
6004         0x0000001d,                                                             /* endloop              */
6005         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
6006         0x0000ffff                                                              /* end                  */
6007     };
6008     const DWORD vshader_code[] = {
6009         0xfffe0300,                                                             /* vs_3_0               */
6010         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
6011         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
6012         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
6013         0x0000ffff                                                              /* end                  */
6014     };
6015     IDirect3DPixelShader9 *shader;
6016     IDirect3DVertexShader9 *vshader;
6017     HRESULT hr;
6018     DWORD color;
6019     const float quad[] = {
6020         -1.0,   -1.0,   0.1,
6021          1.0,   -1.0,   0.1,
6022         -1.0,    1.0,   0.1,
6023          1.0,    1.0,   0.1
6024     };
6025
6026     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6027     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6028     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6029     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6030     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6031     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6032     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6033     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6034     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6035     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6036     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6037     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6038
6039     hr = IDirect3DDevice9_BeginScene(device);
6040     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6041     if(SUCCEEDED(hr))
6042     {
6043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6044         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6045         hr = IDirect3DDevice9_EndScene(device);
6046         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6047     }
6048
6049     color = getPixelColor(device, 360, 240);
6050     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6051        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6052
6053     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6054     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6055
6056     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6057     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6058     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6059     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6060     IDirect3DPixelShader9_Release(shader);
6061     IDirect3DVertexShader9_Release(vshader);
6062 }
6063
6064 struct varying_test_struct
6065 {
6066     const DWORD             *shader_code;
6067     IDirect3DPixelShader9   *shader;
6068     DWORD                   color, color_rhw;
6069     const char              *name;
6070     BOOL                    todo, todo_rhw;
6071 };
6072
6073 struct hugeVertex
6074 {
6075     float pos_x,        pos_y,      pos_z,      rhw;
6076     float weight_1,     weight_2,   weight_3,   weight_4;
6077     float index_1,      index_2,    index_3,    index_4;
6078     float normal_1,     normal_2,   normal_3,   normal_4;
6079     float fog_1,        fog_2,      fog_3,      fog_4;
6080     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
6081     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
6082     float binormal_1,   binormal_2, binormal_3, binormal_4;
6083     float depth_1,      depth_2,    depth_3,    depth_4;
6084     DWORD diffuse, specular;
6085 };
6086
6087 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6088     /* dcl_position: fails to compile */
6089     const DWORD blendweight_code[] = {
6090         0xffff0300,                             /* ps_3_0                   */
6091         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6092         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6093         0x0000ffff                              /* end                      */
6094     };
6095     const DWORD blendindices_code[] = {
6096         0xffff0300,                             /* ps_3_0                   */
6097         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6098         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6099         0x0000ffff                              /* end                      */
6100     };
6101     const DWORD normal_code[] = {
6102         0xffff0300,                             /* ps_3_0                   */
6103         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6104         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6105         0x0000ffff                              /* end                      */
6106     };
6107     /* psize: fails? */
6108     const DWORD texcoord0_code[] = {
6109         0xffff0300,                             /* ps_3_0                   */
6110         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6111         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6112         0x0000ffff                              /* end                      */
6113     };
6114     const DWORD tangent_code[] = {
6115         0xffff0300,                             /* ps_3_0                   */
6116         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6117         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6118         0x0000ffff                              /* end                      */
6119     };
6120     const DWORD binormal_code[] = {
6121         0xffff0300,                             /* ps_3_0                   */
6122         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6123         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6124         0x0000ffff                              /* end                      */
6125     };
6126     /* tessfactor: fails */
6127     /* positiont: fails */
6128     const DWORD color_code[] = {
6129         0xffff0300,                             /* ps_3_0                   */
6130         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6131         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6132         0x0000ffff                              /* end                      */
6133     };
6134     const DWORD fog_code[] = {
6135         0xffff0300,                             /* ps_3_0                   */
6136         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6137         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6138         0x0000ffff                              /* end                      */
6139     };
6140     const DWORD depth_code[] = {
6141         0xffff0300,                             /* ps_3_0                   */
6142         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6143         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6144         0x0000ffff                              /* end                      */
6145     };
6146     const DWORD specular_code[] = {
6147         0xffff0300,                             /* ps_3_0                   */
6148         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6149         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6150         0x0000ffff                              /* end                      */
6151     };
6152     /* sample: fails */
6153
6154     struct varying_test_struct tests[] = {
6155        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6156        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6157        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6158        /* Why does dx not forward the texcoord? */
6159        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6160        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6161        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6162        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6163        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6164        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6165        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6166     };
6167     /* Declare a monster vertex type :-) */
6168     static const D3DVERTEXELEMENT9 decl_elements[] = {
6169         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6170         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6171         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6172         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6173         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6174         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6175         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6176         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6177         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6178         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6179         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6180         D3DDECL_END()
6181     };
6182     struct hugeVertex data[4] = {
6183         {
6184             -1.0,   -1.0,   0.1,    1.0,
6185              0.1,    0.1,   0.1,    0.1,
6186              0.2,    0.2,   0.2,    0.2,
6187              0.3,    0.3,   0.3,    0.3,
6188              0.4,    0.4,   0.4,    0.4,
6189              0.50,   0.55,  0.55,   0.55,
6190              0.6,    0.6,   0.6,    0.7,
6191              0.7,    0.7,   0.7,    0.6,
6192              0.8,    0.8,   0.8,    0.8,
6193              0xe6e6e6e6, /* 0.9 * 256 */
6194              0x224488ff  /* Nothing special */
6195         },
6196         {
6197              1.0,   -1.0,   0.1,    1.0,
6198              0.1,    0.1,   0.1,    0.1,
6199              0.2,    0.2,   0.2,    0.2,
6200              0.3,    0.3,   0.3,    0.3,
6201              0.4,    0.4,   0.4,    0.4,
6202              0.50,   0.55,  0.55,   0.55,
6203              0.6,    0.6,   0.6,    0.7,
6204              0.7,    0.7,   0.7,    0.6,
6205              0.8,    0.8,   0.8,    0.8,
6206              0xe6e6e6e6, /* 0.9 * 256 */
6207              0x224488ff /* Nothing special */
6208         },
6209         {
6210             -1.0,    1.0,   0.1,    1.0,
6211              0.1,    0.1,   0.1,    0.1,
6212              0.2,    0.2,   0.2,    0.2,
6213              0.3,    0.3,   0.3,    0.3,
6214              0.4,    0.4,   0.4,    0.4,
6215              0.50,   0.55,  0.55,   0.55,
6216              0.6,    0.6,   0.6,    0.7,
6217              0.7,    0.7,   0.7,    0.6,
6218              0.8,    0.8,   0.8,    0.8,
6219              0xe6e6e6e6, /* 0.9 * 256 */
6220              0x224488ff /* Nothing special */
6221         },
6222         {
6223              1.0,    1.0,   0.1,    1.0,
6224              0.1,    0.1,   0.1,    0.1,
6225              0.2,    0.2,   0.2,    0.2,
6226              0.3,    0.3,   0.3,    0.3,
6227              0.4,    0.4,   0.4,    0.4,
6228              0.50,   0.55,  0.55,   0.55,
6229              0.6,    0.6,   0.6,    0.7,
6230              0.7,    0.7,   0.7,    0.6,
6231              0.8,    0.8,   0.8,    0.8,
6232              0xe6e6e6e6, /* 0.9 * 256 */
6233              0x224488ff /* Nothing special */
6234         },
6235     };
6236     struct hugeVertex data2[4];
6237     IDirect3DVertexDeclaration9 *decl;
6238     HRESULT hr;
6239     unsigned int i;
6240     DWORD color, r, g, b, r_e, g_e, b_e;
6241
6242     memcpy(data2, data, sizeof(data2));
6243     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6244     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6245     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6246     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6247
6248     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6250     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6251     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6252
6253     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6254     {
6255         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6256         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6257            tests[i].name, hr);
6258     }
6259
6260     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6263     {
6264         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6265         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6266
6267         hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6268         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6269
6270         hr = IDirect3DDevice9_BeginScene(device);
6271         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6272         if(SUCCEEDED(hr))
6273         {
6274             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6275             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6276             hr = IDirect3DDevice9_EndScene(device);
6277             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6278         }
6279
6280         color = getPixelColor(device, 360, 240);
6281         r = color & 0x00ff0000 >> 16;
6282         g = color & 0x0000ff00 >>  8;
6283         b = color & 0x000000ff;
6284         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6285         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6286         b_e = tests[i].color_rhw & 0x000000ff;
6287
6288         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6289         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6290
6291         if(tests[i].todo_rhw) {
6292             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6293              * pipeline
6294              */
6295             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6296                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6297                          tests[i].name, color, tests[i].color_rhw);
6298         } else {
6299             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6300                "Test %s returned color 0x%08x, expected 0x%08x\n",
6301                tests[i].name, color, tests[i].color_rhw);
6302         }
6303     }
6304
6305     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6306     {
6307         IDirect3DPixelShader9_Release(tests[i].shader);
6308     }
6309
6310     IDirect3DVertexDeclaration9_Release(decl);
6311 }
6312
6313 static void test_compare_instructions(IDirect3DDevice9 *device)
6314 {
6315     DWORD shader_sge_vec_code[] = {
6316         0xfffe0101,                                         /* vs_1_1                   */
6317         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6318         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6319         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6320         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6321         0x0000ffff                                          /* end                      */
6322     };
6323     DWORD shader_slt_vec_code[] = {
6324         0xfffe0101,                                         /* vs_1_1                   */
6325         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6326         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6327         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6328         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6329         0x0000ffff                                          /* end                      */
6330     };
6331     DWORD shader_sge_scalar_code[] = {
6332         0xfffe0101,                                         /* vs_1_1                   */
6333         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6334         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6335         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6336         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6337         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6338         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6339         0x0000ffff                                          /* end                      */
6340     };
6341     DWORD shader_slt_scalar_code[] = {
6342         0xfffe0101,                                         /* vs_1_1                   */
6343         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6344         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6345         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6346         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6347         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6348         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6349         0x0000ffff                                          /* end                      */
6350     };
6351     IDirect3DVertexShader9 *shader_sge_vec;
6352     IDirect3DVertexShader9 *shader_slt_vec;
6353     IDirect3DVertexShader9 *shader_sge_scalar;
6354     IDirect3DVertexShader9 *shader_slt_scalar;
6355     HRESULT hr, color;
6356     float quad1[] =  {
6357         -1.0,   -1.0,   0.1,
6358          0.0,   -1.0,   0.1,
6359         -1.0,    0.0,   0.1,
6360          0.0,    0.0,   0.1
6361     };
6362     float quad2[] =  {
6363          0.0,   -1.0,   0.1,
6364          1.0,   -1.0,   0.1,
6365          0.0,    0.0,   0.1,
6366          1.0,    0.0,   0.1
6367     };
6368     float quad3[] =  {
6369         -1.0,    0.0,   0.1,
6370          0.0,    0.0,   0.1,
6371         -1.0,    1.0,   0.1,
6372          0.0,    1.0,   0.1
6373     };
6374     float quad4[] =  {
6375          0.0,    0.0,   0.1,
6376          1.0,    0.0,   0.1,
6377          0.0,    1.0,   0.1,
6378          1.0,    1.0,   0.1
6379     };
6380     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6381     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6382
6383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6384     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6385
6386     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6387     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6388     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6389     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6391     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6393     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6394     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6395     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6396     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6397     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6398     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6400
6401     hr = IDirect3DDevice9_BeginScene(device);
6402     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6403     if(SUCCEEDED(hr))
6404     {
6405         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6406         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6409
6410         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6411         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6413         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6414
6415         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6416         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6418         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6419
6420         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6421         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6422
6423         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6424         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6426         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6427
6428         hr = IDirect3DDevice9_EndScene(device);
6429         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6430     }
6431
6432     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6433     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6434
6435     color = getPixelColor(device, 160, 360);
6436     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6437     color = getPixelColor(device, 480, 360);
6438     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6439     color = getPixelColor(device, 160, 120);
6440     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6441     color = getPixelColor(device, 480, 160);
6442     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6443
6444     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6445     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6446
6447     IDirect3DVertexShader9_Release(shader_sge_vec);
6448     IDirect3DVertexShader9_Release(shader_slt_vec);
6449     IDirect3DVertexShader9_Release(shader_sge_scalar);
6450     IDirect3DVertexShader9_Release(shader_slt_scalar);
6451 }
6452
6453 static void test_vshader_input(IDirect3DDevice9 *device)
6454 {
6455     static const DWORD swapped_shader_code_3[] =
6456     {
6457         0xfffe0300,                                         /* vs_3_0               */
6458         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6459         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6460         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6461         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6462         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6463         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6464         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6465         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6466         0x0000ffff                                          /* end                  */
6467     };
6468     static const DWORD swapped_shader_code_1[] =
6469     {
6470         0xfffe0101,                                         /* vs_1_1               */
6471         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6472         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6473         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6474         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6475         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6476         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6477         0x0000ffff                                          /* end                  */
6478     };
6479     static const DWORD swapped_shader_code_2[] =
6480     {
6481         0xfffe0200,                                         /* vs_2_0               */
6482         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6483         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6484         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6485         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6486         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6487         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6488         0x0000ffff                                          /* end                  */
6489     };
6490     static const DWORD texcoord_color_shader_code_3[] =
6491     {
6492         0xfffe0300,                                         /* vs_3_0               */
6493         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6494         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6495         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6496         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6497         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6498         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6499         0x0000ffff                                          /* end                  */
6500     };
6501     static const DWORD texcoord_color_shader_code_2[] =
6502     {
6503         0xfffe0200,                                         /* vs_2_0               */
6504         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6505         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6506         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6507         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6508         0x0000ffff                                          /* end                  */
6509     };
6510     static const DWORD texcoord_color_shader_code_1[] =
6511     {
6512         0xfffe0101,                                         /* vs_1_1               */
6513         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6514         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6515         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6516         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6517         0x0000ffff                                          /* end                  */
6518     };
6519     static const DWORD color_color_shader_code_3[] =
6520     {
6521         0xfffe0300,                                         /* vs_3_0               */
6522         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6523         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6524         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6525         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6526         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6527         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6528         0x0000ffff                                          /* end                  */
6529     };
6530     static const DWORD color_color_shader_code_2[] =
6531     {
6532         0xfffe0200,                                         /* vs_2_0               */
6533         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6534         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6535         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6536         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6537         0x0000ffff                                          /* end                  */
6538     };
6539     static const DWORD color_color_shader_code_1[] =
6540     {
6541         0xfffe0101,                                         /* vs_1_1               */
6542         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6543         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6544         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6545         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6546         0x0000ffff                                          /* end                  */
6547     };
6548     static const DWORD ps3_code[] =
6549     {
6550         0xffff0300,                                         /* ps_3_0               */
6551         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6552         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6553         0x0000ffff                                          /* end                  */
6554     };
6555     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6556     IDirect3DPixelShader9 *ps;
6557     HRESULT hr;
6558     DWORD color;
6559     float quad1[] =  {
6560         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6561          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6562         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6563          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6564     };
6565     float quad2[] =  {
6566          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6567          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6568          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6569          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6570     };
6571     float quad3[] =  {
6572         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6573          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6574         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6575          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6576     };
6577     float quad4[] =  {
6578          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6579          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6580          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6581          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6582     };
6583     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6584         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6585         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6586         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6587         D3DDECL_END()
6588     };
6589     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6590         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6591         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6592         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6593         D3DDECL_END()
6594     };
6595     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6596         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6597         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6598         D3DDECL_END()
6599     };
6600     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6601         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6602         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6603         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6604         D3DDECL_END()
6605     };
6606     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6607         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6608         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6609         D3DDECL_END()
6610     };
6611     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6612         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6613         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6614         D3DDECL_END()
6615     };
6616     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6617         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6618         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6619         D3DDECL_END()
6620     };
6621     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6622         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6623         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6624         D3DDECL_END()
6625     };
6626     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6627     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6628     unsigned int i;
6629     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6630     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6631
6632     struct vertex quad1_color[] =  {
6633        {-1.0,   -1.0,   0.1,    0x00ff8040},
6634        { 0.0,   -1.0,   0.1,    0x00ff8040},
6635        {-1.0,    0.0,   0.1,    0x00ff8040},
6636        { 0.0,    0.0,   0.1,    0x00ff8040}
6637     };
6638     struct vertex quad2_color[] =  {
6639        { 0.0,   -1.0,   0.1,    0x00ff8040},
6640        { 1.0,   -1.0,   0.1,    0x00ff8040},
6641        { 0.0,    0.0,   0.1,    0x00ff8040},
6642        { 1.0,    0.0,   0.1,    0x00ff8040}
6643     };
6644     struct vertex quad3_color[] =  {
6645        {-1.0,    0.0,   0.1,    0x00ff8040},
6646        { 0.0,    0.0,   0.1,    0x00ff8040},
6647        {-1.0,    1.0,   0.1,    0x00ff8040},
6648        { 0.0,    1.0,   0.1,    0x00ff8040}
6649     };
6650     float quad4_color[] =  {
6651          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6652          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6653          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6654          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6655     };
6656
6657     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6658     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6659     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6660     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6661     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6662     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6663     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6664     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6665
6666     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6667     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6668     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6669     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6670     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6671     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6672     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6673     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6674
6675     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6676     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6677
6678     for(i = 1; i <= 3; i++) {
6679         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6680         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6681         if(i == 3) {
6682             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6683             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6684             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6685             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6686         } else if(i == 2){
6687             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6688             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6689         } else if(i == 1) {
6690             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6691             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6692         }
6693
6694         hr = IDirect3DDevice9_BeginScene(device);
6695         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6696         if(SUCCEEDED(hr))
6697         {
6698             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6699             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6700
6701             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6702             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6703             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6704             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6705
6706             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6707             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6708             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6709             if(i == 3 || i == 2) {
6710                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6711             } else if(i == 1) {
6712                 /* Succeeds or fails, depending on SW or HW vertex processing */
6713                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6714             }
6715
6716             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6717             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6718             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6719             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6720
6721             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6722             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6723             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6724             if(i == 3 || i == 2) {
6725                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6726             } else if(i == 1) {
6727                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6728             }
6729
6730             hr = IDirect3DDevice9_EndScene(device);
6731             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6732         }
6733
6734         if(i == 3 || i == 2) {
6735             color = getPixelColor(device, 160, 360);
6736             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6737                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6738
6739             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6740             color = getPixelColor(device, 480, 360);
6741             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6742                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6743             color = getPixelColor(device, 160, 120);
6744             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6745             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6746                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6747
6748             color = getPixelColor(device, 480, 160);
6749             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6750         } else if(i == 1) {
6751             color = getPixelColor(device, 160, 360);
6752             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6753                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6754             color = getPixelColor(device, 480, 360);
6755             /* Accept the clear color as well in this case, since SW VP returns an error */
6756             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6757             color = getPixelColor(device, 160, 120);
6758             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6759                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6760             color = getPixelColor(device, 480, 160);
6761             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6762         }
6763
6764         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6766
6767         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6768         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6769
6770         /* Now find out if the whole streams are re-read, or just the last active value for the
6771          * vertices is used.
6772          */
6773         hr = IDirect3DDevice9_BeginScene(device);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6775         if(SUCCEEDED(hr))
6776         {
6777             float quad1_modified[] =  {
6778                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6779                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6780                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6781                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6782             };
6783             float quad2_modified[] =  {
6784                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6785                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6786                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6787                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6788             };
6789
6790             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6791             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6792
6793             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6794             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6795             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6796             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6797
6798             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6799             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6800             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6801             if(i == 3 || i == 2) {
6802                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6803             } else if(i == 1) {
6804                 /* Succeeds or fails, depending on SW or HW vertex processing */
6805                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6806             }
6807
6808             hr = IDirect3DDevice9_EndScene(device);
6809             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6810         }
6811
6812         color = getPixelColor(device, 480, 350);
6813         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6814          * as well.
6815          *
6816          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6817          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6818          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6819          * refrast's result.
6820          *
6821          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6822          */
6823         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6824            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6825
6826         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6827         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6828
6829         IDirect3DDevice9_SetVertexShader(device, NULL);
6830         IDirect3DDevice9_SetPixelShader(device, NULL);
6831         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6832
6833         IDirect3DVertexShader9_Release(swapped_shader);
6834     }
6835
6836     for(i = 1; i <= 3; i++) {
6837         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6838         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6839         if(i == 3) {
6840             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6841             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6842             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6843             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6844             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6845             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6846         } else if(i == 2){
6847             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6848             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6849             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6850             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6851         } else if(i == 1) {
6852             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6853             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6854             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6855             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6856         }
6857
6858         hr = IDirect3DDevice9_BeginScene(device);
6859         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6860         if(SUCCEEDED(hr))
6861         {
6862             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6863             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6864             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6865             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6866             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6867             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6868
6869             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6870             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6871
6872             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6873             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6874             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6875             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6877             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6878
6879             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6880             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6881             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6882             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6883             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6884             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6885
6886             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6887             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6888             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6889             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6890
6891             hr = IDirect3DDevice9_EndScene(device);
6892             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6893         }
6894         IDirect3DDevice9_SetVertexShader(device, NULL);
6895         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6896         IDirect3DDevice9_SetPixelShader(device, NULL);
6897
6898         color = getPixelColor(device, 160, 360);
6899         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6900            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6901         color = getPixelColor(device, 480, 360);
6902         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6903            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6904         color = getPixelColor(device, 160, 120);
6905         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6906            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6907         color = getPixelColor(device, 480, 160);
6908         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6909            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6910
6911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6912         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6913
6914         IDirect3DVertexShader9_Release(texcoord_color_shader);
6915         IDirect3DVertexShader9_Release(color_color_shader);
6916     }
6917
6918     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6919     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6920     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6921     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6922
6923     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6924     IDirect3DVertexDeclaration9_Release(decl_color_color);
6925     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6926     IDirect3DVertexDeclaration9_Release(decl_color_float);
6927
6928     IDirect3DPixelShader9_Release(ps);
6929 }
6930
6931 static void srgbtexture_test(IDirect3DDevice9 *device)
6932 {
6933     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6934      * texture stage state to render a quad using that texture.  The resulting
6935      * color components should be 0x36 (~ 0.21), per this formula:
6936      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6937      * This is true where srgb_color > 0.04045.
6938      */
6939     IDirect3D9 *d3d = NULL;
6940     HRESULT hr;
6941     LPDIRECT3DTEXTURE9 texture = NULL;
6942     LPDIRECT3DSURFACE9 surface = NULL;
6943     D3DLOCKED_RECT lr;
6944     DWORD color;
6945     float quad[] = {
6946         -1.0,       1.0,       0.0,     0.0,    0.0,
6947          1.0,       1.0,       0.0,     1.0,    0.0,
6948         -1.0,      -1.0,       0.0,     0.0,    1.0,
6949          1.0,      -1.0,       0.0,     1.0,    1.0,
6950     };
6951
6952
6953     memset(&lr, 0, sizeof(lr));
6954     IDirect3DDevice9_GetDirect3D(device, &d3d);
6955     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6956                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6957                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6958         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6959         goto out;
6960     }
6961
6962     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6963                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6964                                         &texture, NULL);
6965     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6966     if(!texture) {
6967         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6968         goto out;
6969     }
6970     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6971     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6972
6973     fill_surface(surface, 0xff7f7f7f);
6974     IDirect3DSurface9_Release(surface);
6975
6976     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6977     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6978     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6979     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6980
6981     hr = IDirect3DDevice9_BeginScene(device);
6982     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6983     if(SUCCEEDED(hr))
6984     {
6985         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6986         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6987
6988         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6989         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6990
6991
6992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6993         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6994
6995         hr = IDirect3DDevice9_EndScene(device);
6996         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6997     }
6998
6999     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7000     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7001     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7002     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7003
7004     color = getPixelColor(device, 320, 240);
7005     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7006
7007     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7008     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7009
7010 out:
7011     if(texture) IDirect3DTexture9_Release(texture);
7012     IDirect3D9_Release(d3d);
7013 }
7014
7015 static void shademode_test(IDirect3DDevice9 *device)
7016 {
7017     /* Render a quad and try all of the different fixed function shading models. */
7018     HRESULT hr;
7019     DWORD color0, color1;
7020     DWORD color0_gouraud = 0, color1_gouraud = 0;
7021     DWORD shademode = D3DSHADE_FLAT;
7022     DWORD primtype = D3DPT_TRIANGLESTRIP;
7023     LPVOID data = NULL;
7024     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
7025     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
7026     UINT i, j;
7027     struct vertex quad_strip[] =
7028     {
7029         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7030         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7031         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7032         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7033     };
7034     struct vertex quad_list[] =
7035     {
7036         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7037         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7038         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7039
7040         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7041         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7042         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7043     };
7044
7045     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7046                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7047     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7048     if (FAILED(hr)) goto bail;
7049
7050     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7051                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7052     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7053     if (FAILED(hr)) goto bail;
7054
7055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7057
7058     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7059     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7060
7061     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7062     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7063     memcpy(data, quad_strip, sizeof(quad_strip));
7064     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7065     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7066
7067     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7068     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7069     memcpy(data, quad_list, sizeof(quad_list));
7070     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7071     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7072
7073     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
7074      * the color fixups we have to do for FLAT shading will be dependent on that. */
7075     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7076     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7077
7078     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7079     for (j=0; j<2; j++) {
7080
7081         /* Inner loop just changes the D3DRS_SHADEMODE */
7082         for (i=0; i<3; i++) {
7083             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7084             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7085
7086             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7087             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7088
7089             hr = IDirect3DDevice9_BeginScene(device);
7090             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7091             if(SUCCEEDED(hr))
7092             {
7093                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7094                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7095
7096                 hr = IDirect3DDevice9_EndScene(device);
7097                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7098             }
7099
7100             /* Sample two spots from the output */
7101             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7102             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7103             switch(shademode) {
7104                 case D3DSHADE_FLAT:
7105                     /* Should take the color of the first vertex of each triangle */
7106                     if (0)
7107                     {
7108                         /* This test depends on EXT_provoking_vertex being
7109                          * available. This extension is currently (20090810)
7110                          * not common enough to let the test fail if it isn't
7111                          * present. */
7112                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7113                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7114                     }
7115                     shademode = D3DSHADE_GOURAUD;
7116                     break;
7117                 case D3DSHADE_GOURAUD:
7118                     /* Should be an interpolated blend */
7119
7120                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7121                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7122                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7123                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7124
7125                     color0_gouraud = color0;
7126                     color1_gouraud = color1;
7127
7128                     shademode = D3DSHADE_PHONG;
7129                     break;
7130                 case D3DSHADE_PHONG:
7131                     /* Should be the same as GOURAUD, since no hardware implements this */
7132                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7133                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7134                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7135                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7136
7137                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7138                             color0_gouraud, color0);
7139                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7140                             color1_gouraud, color1);
7141                     break;
7142             }
7143         }
7144
7145         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7146         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7147
7148         /* Now, do it all over again with a TRIANGLELIST */
7149         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7150         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7151         primtype = D3DPT_TRIANGLELIST;
7152         shademode = D3DSHADE_FLAT;
7153     }
7154
7155 bail:
7156     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7157     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7159     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7160
7161     if (vb_strip)
7162         IDirect3DVertexBuffer9_Release(vb_strip);
7163     if (vb_list)
7164         IDirect3DVertexBuffer9_Release(vb_list);
7165 }
7166
7167 static void alpha_test(IDirect3DDevice9 *device)
7168 {
7169     HRESULT hr;
7170     IDirect3DTexture9 *offscreenTexture;
7171     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7172     DWORD color;
7173
7174     struct vertex quad1[] =
7175     {
7176         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7177         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7178         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7179         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7180     };
7181     struct vertex quad2[] =
7182     {
7183         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7184         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7185         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7186         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7187     };
7188     static const float composite_quad[][5] = {
7189         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7190         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7191         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7192         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7193     };
7194
7195     /* Clear the render target with alpha = 0.5 */
7196     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7197     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7198
7199     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7200     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7201
7202     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7203     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7204     if(!backbuffer) {
7205         goto out;
7206     }
7207
7208     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7209     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7210     if(!offscreen) {
7211         goto out;
7212     }
7213
7214     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7215     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7216
7217     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7218     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7219     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7220     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7221     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7222     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7223     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7224     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7225     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7226     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7227
7228     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7229     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7230     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7231
7232         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7234         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7235         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7236         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7237         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7238         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7239
7240         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7241         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7242         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7243         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7245         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7246
7247         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7248          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7249          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7250         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7251         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7252         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7253         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7254
7255         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7256         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7257         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7258         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7259         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7260         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7261
7262         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7263         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7264         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7265         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7266         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7267         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7268
7269         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7270         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7271
7272         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7273          * Disable alpha blending for the final composition
7274          */
7275         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7276         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7277         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7278         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7279
7280         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7281         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7283         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7284         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7285         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7286
7287         hr = IDirect3DDevice9_EndScene(device);
7288         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7289     }
7290
7291     color = getPixelColor(device, 160, 360);
7292     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7293        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7294
7295     color = getPixelColor(device, 160, 120);
7296     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7297        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7298
7299     color = getPixelColor(device, 480, 360);
7300     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7301        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7302
7303     color = getPixelColor(device, 480, 120);
7304     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7305        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7306
7307     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7308
7309     out:
7310     /* restore things */
7311     if(backbuffer) {
7312         IDirect3DSurface9_Release(backbuffer);
7313     }
7314     if(offscreenTexture) {
7315         IDirect3DTexture9_Release(offscreenTexture);
7316     }
7317     if(offscreen) {
7318         IDirect3DSurface9_Release(offscreen);
7319     }
7320 }
7321
7322 struct vertex_shortcolor {
7323     float x, y, z;
7324     unsigned short r, g, b, a;
7325 };
7326 struct vertex_floatcolor {
7327     float x, y, z;
7328     float r, g, b, a;
7329 };
7330
7331 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7332 {
7333     HRESULT hr;
7334     BOOL s_ok, ub_ok, f_ok;
7335     DWORD color, size, i;
7336     void *data;
7337     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7338         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7339         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7340         D3DDECL_END()
7341     };
7342     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7343         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7344         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7345         D3DDECL_END()
7346     };
7347     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7348         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7349         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7350         D3DDECL_END()
7351     };
7352     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7353         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7354         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7355         D3DDECL_END()
7356     };
7357     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7358         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7359         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7360         D3DDECL_END()
7361     };
7362     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7363         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7364         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7365         D3DDECL_END()
7366     };
7367     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7368         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7369         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7370         D3DDECL_END()
7371     };
7372     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7373     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7374     IDirect3DVertexBuffer9 *vb, *vb2;
7375     struct vertex quad1[] =                             /* D3DCOLOR */
7376     {
7377         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7378         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7379         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7380         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7381     };
7382     struct vertex quad2[] =                             /* UBYTE4N */
7383     {
7384         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7385         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7386         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7387         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7388     };
7389     struct vertex_shortcolor quad3[] =                  /* short */
7390     {
7391         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7392         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7393         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7394         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7395     };
7396     struct vertex_floatcolor quad4[] =
7397     {
7398         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7399         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7400         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7401         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7402     };
7403     DWORD colors[] = {
7404         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7405         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7406         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7407         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7408         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7409         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7410         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7411         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7412         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7413         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7414         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7415         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7416         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7417         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7418         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7419         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7420     };
7421     float quads[] = {
7422         -1.0,   -1.0,     0.1,
7423         -1.0,    0.0,     0.1,
7424          0.0,   -1.0,     0.1,
7425          0.0,    0.0,     0.1,
7426
7427          0.0,   -1.0,     0.1,
7428          0.0,    0.0,     0.1,
7429          1.0,   -1.0,     0.1,
7430          1.0,    0.0,     0.1,
7431
7432          0.0,    0.0,     0.1,
7433          0.0,    1.0,     0.1,
7434          1.0,    0.0,     0.1,
7435          1.0,    1.0,     0.1,
7436
7437         -1.0,    0.0,     0.1,
7438         -1.0,    1.0,     0.1,
7439          0.0,    0.0,     0.1,
7440          0.0,    1.0,     0.1
7441     };
7442     struct tvertex quad_transformed[] = {
7443        {  90,    110,     0.1,      2.0,        0x00ffff00},
7444        { 570,    110,     0.1,      2.0,        0x00ffff00},
7445        {  90,    300,     0.1,      2.0,        0x00ffff00},
7446        { 570,    300,     0.1,      2.0,        0x00ffff00}
7447     };
7448     D3DCAPS9 caps;
7449
7450     memset(&caps, 0, sizeof(caps));
7451     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7452     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7453
7454     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7455     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7456
7457     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7458     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7459     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7460     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7461     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7462     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7463     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7464         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7465         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7466         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7467         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7468     } else {
7469         trace("D3DDTCAPS_UBYTE4N not supported\n");
7470         dcl_ubyte_2 = NULL;
7471         dcl_ubyte = NULL;
7472     }
7473     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7474     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7475     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7476     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7477
7478     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7479     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7480                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7481     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7482
7483     hr = IDirect3DDevice9_BeginScene(device);
7484     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7485     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7486     if(SUCCEEDED(hr)) {
7487         if(dcl_color) {
7488             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7489             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7490             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7491             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7492         }
7493
7494         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7495          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7496          * using software vertex processing. Doh!
7497          */
7498         if(dcl_ubyte) {
7499             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7500             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7501             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7502             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7503             ub_ok = SUCCEEDED(hr);
7504         }
7505
7506         if(dcl_short) {
7507             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7508             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7509             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7510             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7511             s_ok = SUCCEEDED(hr);
7512         }
7513
7514         if(dcl_float) {
7515             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7516             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7517             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7518             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7519             f_ok = SUCCEEDED(hr);
7520         }
7521
7522         hr = IDirect3DDevice9_EndScene(device);
7523         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7524     }
7525
7526     if(dcl_short) {
7527         color = getPixelColor(device, 480, 360);
7528         ok(color == 0x000000ff || !s_ok,
7529            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7530     }
7531     if(dcl_ubyte) {
7532         color = getPixelColor(device, 160, 120);
7533         ok(color == 0x0000ffff || !ub_ok,
7534            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7535     }
7536     if(dcl_color) {
7537         color = getPixelColor(device, 160, 360);
7538         ok(color == 0x00ffff00,
7539            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7540     }
7541     if(dcl_float) {
7542         color = getPixelColor(device, 480, 120);
7543         ok(color == 0x00ff0000 || !f_ok,
7544            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7545     }
7546     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7547
7548     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7549      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7550      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7551      * whether the immediate mode code works
7552      */
7553     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7554     hr = IDirect3DDevice9_BeginScene(device);
7555     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7556     if(SUCCEEDED(hr)) {
7557         if(dcl_color) {
7558             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7559             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7560             memcpy(data, quad1, sizeof(quad1));
7561             hr = IDirect3DVertexBuffer9_Unlock(vb);
7562             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7563             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7564             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7565             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7566             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7567             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7568             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7569         }
7570
7571         if(dcl_ubyte) {
7572             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7573             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7574             memcpy(data, quad2, sizeof(quad2));
7575             hr = IDirect3DVertexBuffer9_Unlock(vb);
7576             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7577             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7578             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7579             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7580             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7581             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7582             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7583                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7584             ub_ok = SUCCEEDED(hr);
7585         }
7586
7587         if(dcl_short) {
7588             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7589             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7590             memcpy(data, quad3, sizeof(quad3));
7591             hr = IDirect3DVertexBuffer9_Unlock(vb);
7592             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7593             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7594             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7595             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7596             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7597             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7598             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7599                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7600             s_ok = SUCCEEDED(hr);
7601         }
7602
7603         if(dcl_float) {
7604             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7605             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7606             memcpy(data, quad4, sizeof(quad4));
7607             hr = IDirect3DVertexBuffer9_Unlock(vb);
7608             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7609             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7610             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7611             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7612             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7613             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7614             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7615                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7616             f_ok = SUCCEEDED(hr);
7617         }
7618
7619         hr = IDirect3DDevice9_EndScene(device);
7620         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7621     }
7622
7623     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7624     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7625     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7626     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7627
7628     if(dcl_short) {
7629         color = getPixelColor(device, 480, 360);
7630         ok(color == 0x000000ff || !s_ok,
7631            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7632     }
7633     if(dcl_ubyte) {
7634         color = getPixelColor(device, 160, 120);
7635         ok(color == 0x0000ffff || !ub_ok,
7636            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7637     }
7638     if(dcl_color) {
7639         color = getPixelColor(device, 160, 360);
7640         ok(color == 0x00ffff00,
7641            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7642     }
7643     if(dcl_float) {
7644         color = getPixelColor(device, 480, 120);
7645         ok(color == 0x00ff0000 || !f_ok,
7646            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7647     }
7648     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7649
7650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7652
7653     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7654     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7655     memcpy(data, quad_transformed, sizeof(quad_transformed));
7656     hr = IDirect3DVertexBuffer9_Unlock(vb);
7657     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7658
7659     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7660     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7661
7662     hr = IDirect3DDevice9_BeginScene(device);
7663     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7664     if(SUCCEEDED(hr)) {
7665         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7666         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7667         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7668         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7669
7670         hr = IDirect3DDevice9_EndScene(device);
7671         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7672     }
7673
7674     color = getPixelColor(device, 88, 108);
7675     ok(color == 0x000000ff,
7676        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7677     color = getPixelColor(device, 92, 108);
7678     ok(color == 0x000000ff,
7679        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7680     color = getPixelColor(device, 88, 112);
7681     ok(color == 0x000000ff,
7682        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7683     color = getPixelColor(device, 92, 112);
7684     ok(color == 0x00ffff00,
7685        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7686
7687     color = getPixelColor(device, 568, 108);
7688     ok(color == 0x000000ff,
7689        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7690     color = getPixelColor(device, 572, 108);
7691     ok(color == 0x000000ff,
7692        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7693     color = getPixelColor(device, 568, 112);
7694     ok(color == 0x00ffff00,
7695        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7696     color = getPixelColor(device, 572, 112);
7697     ok(color == 0x000000ff,
7698        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7699
7700     color = getPixelColor(device, 88, 298);
7701     ok(color == 0x000000ff,
7702        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7703     color = getPixelColor(device, 92, 298);
7704     ok(color == 0x00ffff00,
7705        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7706     color = getPixelColor(device, 88, 302);
7707     ok(color == 0x000000ff,
7708        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7709     color = getPixelColor(device, 92, 302);
7710     ok(color == 0x000000ff,
7711        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7712
7713     color = getPixelColor(device, 568, 298);
7714     ok(color == 0x00ffff00,
7715        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7716     color = getPixelColor(device, 572, 298);
7717     ok(color == 0x000000ff,
7718        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7719     color = getPixelColor(device, 568, 302);
7720     ok(color == 0x000000ff,
7721        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7722     color = getPixelColor(device, 572, 302);
7723     ok(color == 0x000000ff,
7724        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7725
7726     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7727
7728     /* This test is pointless without those two declarations: */
7729     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7730         skip("color-ubyte switching test declarations aren't supported\n");
7731         goto out;
7732     }
7733
7734     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7735     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7736     memcpy(data, quads, sizeof(quads));
7737     hr = IDirect3DVertexBuffer9_Unlock(vb);
7738     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7739     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7740                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7741     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7742     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7743     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7744     memcpy(data, colors, sizeof(colors));
7745     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7746     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7747
7748     for(i = 0; i < 2; i++) {
7749         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7750         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7751
7752         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7753         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7754         if(i == 0) {
7755             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7756         } else {
7757             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7758         }
7759         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7760
7761         hr = IDirect3DDevice9_BeginScene(device);
7762         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7763         ub_ok = FALSE;
7764         if(SUCCEEDED(hr)) {
7765             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7766             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7767             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7768             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7769                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7770             ub_ok = SUCCEEDED(hr);
7771
7772             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7773             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7774             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7775             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7776
7777             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7778             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7779             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7780             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7781                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7782             ub_ok = (SUCCEEDED(hr) && ub_ok);
7783
7784             hr = IDirect3DDevice9_EndScene(device);
7785             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7786         }
7787
7788         if(i == 0) {
7789             color = getPixelColor(device, 480, 360);
7790             ok(color == 0x00ff0000,
7791                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7792             color = getPixelColor(device, 160, 120);
7793             ok(color == 0x00ffffff,
7794                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7795             color = getPixelColor(device, 160, 360);
7796             ok(color == 0x000000ff || !ub_ok,
7797                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7798             color = getPixelColor(device, 480, 120);
7799             ok(color == 0x000000ff || !ub_ok,
7800                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7801         } else {
7802             color = getPixelColor(device, 480, 360);
7803             ok(color == 0x000000ff,
7804                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7805             color = getPixelColor(device, 160, 120);
7806             ok(color == 0x00ffffff,
7807                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7808             color = getPixelColor(device, 160, 360);
7809             ok(color == 0x00ff0000 || !ub_ok,
7810                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7811             color = getPixelColor(device, 480, 120);
7812             ok(color == 0x00ff0000 || !ub_ok,
7813                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7814         }
7815         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7816     }
7817
7818     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7819     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7820     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7821     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7822     IDirect3DVertexBuffer9_Release(vb2);
7823
7824     out:
7825     IDirect3DVertexBuffer9_Release(vb);
7826     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7827     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7828     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7829     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7830     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7831     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7832     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7833 }
7834
7835 struct vertex_float16color {
7836     float x, y, z;
7837     DWORD c1, c2;
7838 };
7839
7840 static void test_vshader_float16(IDirect3DDevice9 *device)
7841 {
7842     HRESULT hr;
7843     DWORD color;
7844     void *data;
7845     static const D3DVERTEXELEMENT9 decl_elements[] = {
7846         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7847         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7848         D3DDECL_END()
7849     };
7850     IDirect3DVertexDeclaration9 *vdecl = NULL;
7851     IDirect3DVertexBuffer9 *buffer = NULL;
7852     IDirect3DVertexShader9 *shader;
7853     DWORD shader_code[] = {
7854         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7855         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7856         0x90e40001, 0x0000ffff
7857     };
7858     struct vertex_float16color quad[] = {
7859         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7860         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7861         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7862         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7863
7864         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7865         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7866         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7867         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7868
7869         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7870         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7871         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7872         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7873
7874         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7875         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7876         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7877         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7878     };
7879
7880     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7881     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7882
7883     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7884     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7885     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7886     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7887     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7888     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7889
7890     hr = IDirect3DDevice9_BeginScene(device);
7891     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7892     if(SUCCEEDED(hr)) {
7893         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7894         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7895         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7896         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7897         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7898         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7899         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7900         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7902         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7903
7904         hr = IDirect3DDevice9_EndScene(device);
7905         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7906     }
7907     color = getPixelColor(device, 480, 360);
7908     ok(color == 0x00ff0000,
7909        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7910     color = getPixelColor(device, 160, 120);
7911     ok(color == 0x00000000,
7912        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7913     color = getPixelColor(device, 160, 360);
7914     ok(color == 0x0000ff00,
7915        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7916     color = getPixelColor(device, 480, 120);
7917     ok(color == 0x000000ff,
7918        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7919     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7920
7921     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7922     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7923
7924     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7925                                              D3DPOOL_MANAGED, &buffer, NULL);
7926     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7927     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7928     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7929     memcpy(data, quad, sizeof(quad));
7930     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7931     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7932     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7933     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7934
7935     hr = IDirect3DDevice9_BeginScene(device);
7936     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7937     if(SUCCEEDED(hr)) {
7938             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7939             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7940             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7941             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7942             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7943             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7944             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7945             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7946
7947             hr = IDirect3DDevice9_EndScene(device);
7948             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7949     }
7950
7951     color = getPixelColor(device, 480, 360);
7952     ok(color == 0x00ff0000,
7953        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7954     color = getPixelColor(device, 160, 120);
7955     ok(color == 0x00000000,
7956        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7957     color = getPixelColor(device, 160, 360);
7958     ok(color == 0x0000ff00,
7959        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7960     color = getPixelColor(device, 480, 120);
7961     ok(color == 0x000000ff,
7962        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7963     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7964
7965     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7966     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7967     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7968     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7969     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7970     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7971
7972     IDirect3DVertexDeclaration9_Release(vdecl);
7973     IDirect3DVertexShader9_Release(shader);
7974     IDirect3DVertexBuffer9_Release(buffer);
7975 }
7976
7977 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7978 {
7979     D3DCAPS9 caps;
7980     IDirect3DTexture9 *texture;
7981     HRESULT hr;
7982     D3DLOCKED_RECT rect;
7983     unsigned int x, y;
7984     DWORD *dst, color;
7985     const float quad[] = {
7986         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7987          1.0,   -1.0,   0.1,    1.2,   -0.2,
7988         -1.0,    1.0,   0.1,   -0.2,    1.2,
7989          1.0,    1.0,   0.1,    1.2,    1.2
7990     };
7991     memset(&caps, 0, sizeof(caps));
7992
7993     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7994     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7995     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7996     {
7997         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7998         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7999                 "Card has conditional NP2 support without power of two restriction set\n");
8000     }
8001     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8002     {
8003         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8004         return;
8005     }
8006     else
8007     {
8008         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8009         return;
8010     }
8011
8012     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8013     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8014
8015     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8016     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8017
8018     memset(&rect, 0, sizeof(rect));
8019     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8020     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8021     for(y = 0; y < 10; y++) {
8022         for(x = 0; x < 10; x++) {
8023             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8024             if(x == 0 || x == 9 || y == 0 || y == 9) {
8025                 *dst = 0x00ff0000;
8026             } else {
8027                 *dst = 0x000000ff;
8028             }
8029         }
8030     }
8031     hr = IDirect3DTexture9_UnlockRect(texture, 0);
8032     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8033
8034     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8035     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8036     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8037     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8038     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8040     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8041     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8042
8043     hr = IDirect3DDevice9_BeginScene(device);
8044     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8045     if(SUCCEEDED(hr)) {
8046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8047         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8048
8049         hr = IDirect3DDevice9_EndScene(device);
8050         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8051     }
8052
8053     color = getPixelColor(device,    1,  1);
8054     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8055     color = getPixelColor(device, 639, 479);
8056     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8057
8058     color = getPixelColor(device, 135, 101);
8059     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8060     color = getPixelColor(device, 140, 101);
8061     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8062     color = getPixelColor(device, 135, 105);
8063     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8064     color = getPixelColor(device, 140, 105);
8065     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8066
8067     color = getPixelColor(device, 135, 376);
8068     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8069     color = getPixelColor(device, 140, 376);
8070     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8071     color = getPixelColor(device, 135, 379);
8072     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8073     color = getPixelColor(device, 140, 379);
8074     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8075
8076     color = getPixelColor(device, 500, 101);
8077     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8078     color = getPixelColor(device, 504, 101);
8079     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8080     color = getPixelColor(device, 500, 105);
8081     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8082     color = getPixelColor(device, 504, 105);
8083     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8084
8085     color = getPixelColor(device, 500, 376);
8086     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8087     color = getPixelColor(device, 504, 376);
8088     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8089     color = getPixelColor(device, 500, 380);
8090     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8091     color = getPixelColor(device, 504, 380);
8092     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8093
8094     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8095
8096     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8097     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8098     IDirect3DTexture9_Release(texture);
8099 }
8100
8101 static void vFace_register_test(IDirect3DDevice9 *device)
8102 {
8103     HRESULT hr;
8104     DWORD color;
8105     const DWORD shader_code[] = {
8106         0xffff0300,                                                             /* ps_3_0                     */
8107         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8108         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8109         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8110         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8111         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8112         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8113         0x0000ffff                                                              /* END                        */
8114     };
8115     const DWORD vshader_code[] = {
8116         0xfffe0300,                                                             /* vs_3_0               */
8117         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8118         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8119         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8120         0x0000ffff                                                              /* end                  */
8121     };
8122     IDirect3DPixelShader9 *shader;
8123     IDirect3DVertexShader9 *vshader;
8124     IDirect3DTexture9 *texture;
8125     IDirect3DSurface9 *surface, *backbuffer;
8126     const float quad[] = {
8127         -1.0,   -1.0,   0.1,
8128          1.0,   -1.0,   0.1,
8129         -1.0,    0.0,   0.1,
8130
8131          1.0,   -1.0,   0.1,
8132          1.0,    0.0,   0.1,
8133         -1.0,    0.0,   0.1,
8134
8135         -1.0,    0.0,   0.1,
8136         -1.0,    1.0,   0.1,
8137          1.0,    0.0,   0.1,
8138
8139          1.0,    0.0,   0.1,
8140         -1.0,    1.0,   0.1,
8141          1.0,    1.0,   0.1,
8142     };
8143     const float blit[] = {
8144          0.0,   -1.0,   0.1,    0.0,    0.0,
8145          1.0,   -1.0,   0.1,    1.0,    0.0,
8146          0.0,    1.0,   0.1,    0.0,    1.0,
8147          1.0,    1.0,   0.1,    1.0,    1.0,
8148     };
8149
8150     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8151     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8152     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8153     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8154     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8156     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8157     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8158     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8159     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8160     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8161     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8162     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8163     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8164     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8165     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8166
8167     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8168     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8169
8170     hr = IDirect3DDevice9_BeginScene(device);
8171     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8172     if(SUCCEEDED(hr)) {
8173         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8174         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8175         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8176         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8177         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8178         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8179         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8180         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8181         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8182         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8183         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8184
8185         /* Blit the texture onto the back buffer to make it visible */
8186         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8187         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8188         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8189         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8190         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8191         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8192         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8193         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8194         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8195         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8196         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8197         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8198
8199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8200         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8201
8202         hr = IDirect3DDevice9_EndScene(device);
8203         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8204     }
8205
8206     color = getPixelColor(device, 160, 360);
8207     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8208     color = getPixelColor(device, 160, 120);
8209     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8210     color = getPixelColor(device, 480, 360);
8211     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8212     color = getPixelColor(device, 480, 120);
8213     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8214     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8215     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8216
8217     IDirect3DDevice9_SetTexture(device, 0, NULL);
8218     IDirect3DPixelShader9_Release(shader);
8219     IDirect3DVertexShader9_Release(vshader);
8220     IDirect3DSurface9_Release(surface);
8221     IDirect3DSurface9_Release(backbuffer);
8222     IDirect3DTexture9_Release(texture);
8223 }
8224
8225 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8226 {
8227     HRESULT hr;
8228     DWORD color;
8229     int i;
8230     D3DCAPS9 caps;
8231     BOOL L6V5U5_supported = FALSE;
8232     IDirect3DTexture9 *tex1, *tex2;
8233     D3DLOCKED_RECT locked_rect;
8234
8235     static const float quad[][7] = {
8236         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8237         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8238         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8239         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8240     };
8241
8242     static const D3DVERTEXELEMENT9 decl_elements[] = {
8243         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8244         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8245         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8246         D3DDECL_END()
8247     };
8248
8249     /* use asymmetric matrix to test loading */
8250     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8251     float scale, offset;
8252
8253     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8254     IDirect3DTexture9           *texture            = NULL;
8255
8256     memset(&caps, 0, sizeof(caps));
8257     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8258     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8259     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8260         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8261         return;
8262     } else {
8263         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8264          * They report that it is not supported, but after that bump mapping works properly. So just test
8265          * if the format is generally supported, and check the BUMPENVMAP flag
8266          */
8267         IDirect3D9 *d3d9;
8268
8269         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8270         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8271                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8272         L6V5U5_supported = SUCCEEDED(hr);
8273         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8274                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8275         IDirect3D9_Release(d3d9);
8276         if(FAILED(hr)) {
8277             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8278             return;
8279         }
8280     }
8281
8282     /* Generate the textures */
8283     generate_bumpmap_textures(device);
8284
8285     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8286     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8287     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8288     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8289     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8290     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8291     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8292     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8293
8294     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8295     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8296     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8297     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8298     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8299     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8300
8301     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8302     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8303     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8304     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8305     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8306     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8307
8308     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8309     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8310
8311     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8312     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8313
8314     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8315     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8316
8317
8318     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8319     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8320     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8321     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8322
8323     hr = IDirect3DDevice9_BeginScene(device);
8324     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8325
8326     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8327     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8328
8329     hr = IDirect3DDevice9_EndScene(device);
8330     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8331
8332     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8333      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8334      * But since testing the color match is not the purpose of the test don't be too picky
8335      */
8336     color = getPixelColor(device, 320-32, 240);
8337     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8338     color = getPixelColor(device, 320+32, 240);
8339     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8340     color = getPixelColor(device, 320, 240-32);
8341     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8342     color = getPixelColor(device, 320, 240+32);
8343     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8344     color = getPixelColor(device, 320, 240);
8345     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8346     color = getPixelColor(device, 320+32, 240+32);
8347     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8348     color = getPixelColor(device, 320-32, 240+32);
8349     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8350     color = getPixelColor(device, 320+32, 240-32);
8351     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8352     color = getPixelColor(device, 320-32, 240-32);
8353     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8354     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8355     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8356
8357     for(i = 0; i < 2; i++) {
8358         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8359         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8360         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8361         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8362         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8363         IDirect3DTexture9_Release(texture); /* To destroy it */
8364     }
8365
8366     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8367         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8368         goto cleanup;
8369     }
8370     if(L6V5U5_supported == FALSE) {
8371         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8372         goto cleanup;
8373     }
8374
8375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8377     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8378      * would only make this test more complicated
8379      */
8380     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8381     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8382     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8383     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8384
8385     memset(&locked_rect, 0, sizeof(locked_rect));
8386     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8387     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8388     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8389     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8390     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8391
8392     memset(&locked_rect, 0, sizeof(locked_rect));
8393     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8394     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8395     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8396     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8397     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8398
8399     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8400     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8401     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8402     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8403
8404     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8405     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8406     scale = 2.0;
8407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8408     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8409     offset = 0.1;
8410     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8411     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8412
8413     hr = IDirect3DDevice9_BeginScene(device);
8414     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8415     if(SUCCEEDED(hr)) {
8416         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8417         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8418         hr = IDirect3DDevice9_EndScene(device);
8419         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8420     }
8421
8422     color = getPixelColor(device, 320, 240);
8423     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8424      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8425      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8426      */
8427     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8428     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8429     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8430
8431     /* Check a result scale factor > 1.0 */
8432     scale = 10;
8433     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8434     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8435     offset = 10;
8436     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8437     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8438
8439     hr = IDirect3DDevice9_BeginScene(device);
8440     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8441     if(SUCCEEDED(hr)) {
8442         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8443         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8444         hr = IDirect3DDevice9_EndScene(device);
8445         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8446     }
8447     color = getPixelColor(device, 320, 240);
8448     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8449     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8450     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8451
8452     /* Check clamping in the scale factor calculation */
8453     scale = 1000;
8454     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8455     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8456     offset = -1;
8457     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8458     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8459
8460     hr = IDirect3DDevice9_BeginScene(device);
8461     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8462     if(SUCCEEDED(hr)) {
8463         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8464         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8465         hr = IDirect3DDevice9_EndScene(device);
8466         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8467     }
8468     color = getPixelColor(device, 320, 240);
8469     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8470     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8471     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8472
8473     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8474     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8475     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8476     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8477
8478     IDirect3DTexture9_Release(tex1);
8479     IDirect3DTexture9_Release(tex2);
8480
8481 cleanup:
8482     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8483     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8484     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8485     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8486
8487     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8488     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8489     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8490 }
8491
8492 static void stencil_cull_test(IDirect3DDevice9 *device) {
8493     HRESULT hr;
8494     IDirect3DSurface9 *depthstencil = NULL;
8495     D3DSURFACE_DESC desc;
8496     float quad1[] = {
8497         -1.0,   -1.0,   0.1,
8498          0.0,   -1.0,   0.1,
8499         -1.0,    0.0,   0.1,
8500          0.0,    0.0,   0.1,
8501     };
8502     float quad2[] = {
8503          0.0,   -1.0,   0.1,
8504          1.0,   -1.0,   0.1,
8505          0.0,    0.0,   0.1,
8506          1.0,    0.0,   0.1,
8507     };
8508     float quad3[] = {
8509         0.0,    0.0,   0.1,
8510         1.0,    0.0,   0.1,
8511         0.0,    1.0,   0.1,
8512         1.0,    1.0,   0.1,
8513     };
8514     float quad4[] = {
8515         -1.0,    0.0,   0.1,
8516          0.0,    0.0,   0.1,
8517         -1.0,    1.0,   0.1,
8518          0.0,    1.0,   0.1,
8519     };
8520     struct vertex painter[] = {
8521        {-1.0,   -1.0,   0.0,    0x00000000},
8522        { 1.0,   -1.0,   0.0,    0x00000000},
8523        {-1.0,    1.0,   0.0,    0x00000000},
8524        { 1.0,    1.0,   0.0,    0x00000000},
8525     };
8526     WORD indices_cw[]  = {0, 1, 3};
8527     WORD indices_ccw[] = {0, 2, 3};
8528     unsigned int i;
8529     DWORD color;
8530
8531     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8532     if(depthstencil == NULL) {
8533         skip("No depth stencil buffer\n");
8534         return;
8535     }
8536     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8537     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8538     IDirect3DSurface9_Release(depthstencil);
8539     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8540         skip("No 4 or 8 bit stencil surface\n");
8541         return;
8542     }
8543
8544     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8546     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8547     ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8548
8549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8550     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8552     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8553     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8554     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8555     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8556     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8557
8558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8559     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8561     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8563     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8564
8565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8566     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8568     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8569
8570     /* First pass: Fill the stencil buffer with some values... */
8571     hr = IDirect3DDevice9_BeginScene(device);
8572     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8573     if(SUCCEEDED(hr))
8574     {
8575         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8576         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8577         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8578                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8579         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8580         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8581                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8582         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8583
8584         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8585         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8586         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8587         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8588         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8589                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8590         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8591         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8592                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8593         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8594
8595         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8596         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8597         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8598                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8599         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8600         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8601                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8602         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8603
8604         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8605         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8606         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8607                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8608         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8609         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8610                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8611         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8612
8613         hr = IDirect3DDevice9_EndScene(device);
8614         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8615     }
8616
8617     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8618     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8619     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8620     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8621     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8624     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8627     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8628     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8629
8630     /* 2nd pass: Make the stencil values visible */
8631     hr = IDirect3DDevice9_BeginScene(device);
8632     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8633     if(SUCCEEDED(hr))
8634     {
8635         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8636         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8637         for (i = 0; i < 16; ++i)
8638         {
8639             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8640             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8641
8642             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8643             painter[1].diffuse = (i * 16);
8644             painter[2].diffuse = (i * 16);
8645             painter[3].diffuse = (i * 16);
8646             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8647             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8648         }
8649         hr = IDirect3DDevice9_EndScene(device);
8650         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8651     }
8652
8653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8654     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8655
8656     color = getPixelColor(device, 160, 420);
8657     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8658     color = getPixelColor(device, 160, 300);
8659     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8660
8661     color = getPixelColor(device, 480, 420);
8662     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8663     color = getPixelColor(device, 480, 300);
8664     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8665
8666     color = getPixelColor(device, 160, 180);
8667     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8668     color = getPixelColor(device, 160, 60);
8669     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8670
8671     color = getPixelColor(device, 480, 180);
8672     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8673     color = getPixelColor(device, 480, 60);
8674     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8675
8676     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8678 }
8679
8680 static void vpos_register_test(IDirect3DDevice9 *device)
8681 {
8682     HRESULT hr;
8683     DWORD color;
8684     const DWORD shader_code[] = {
8685     0xffff0300,                                                             /* ps_3_0                     */
8686     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8687     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8688     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8689     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8690     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8691     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8692     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8693     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8694     0x0000ffff                                                              /* end                        */
8695     };
8696     const DWORD shader_frac_code[] = {
8697     0xffff0300,                                                             /* ps_3_0                     */
8698     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8699     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8700     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8701     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8702     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8703     0x0000ffff                                                              /* end                        */
8704     };
8705     const DWORD vshader_code[] = {
8706         0xfffe0300,                                                             /* vs_3_0               */
8707         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8708         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8709         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8710         0x0000ffff                                                              /* end                  */
8711     };
8712     IDirect3DVertexShader9 *vshader;
8713     IDirect3DPixelShader9 *shader, *shader_frac;
8714     IDirect3DSurface9 *surface = NULL, *backbuffer;
8715     const float quad[] = {
8716         -1.0,   -1.0,   0.1,    0.0,    0.0,
8717          1.0,   -1.0,   0.1,    1.0,    0.0,
8718         -1.0,    1.0,   0.1,    0.0,    1.0,
8719          1.0,    1.0,   0.1,    1.0,    1.0,
8720     };
8721     D3DLOCKED_RECT lr;
8722     float constant[4] = {1.0, 0.0, 320, 240};
8723     DWORD *pos;
8724
8725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8726     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8727     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8728     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8729     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8730     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8731     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8732     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8733     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8735     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8736     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8737     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8738     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8739     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8740     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8741
8742     hr = IDirect3DDevice9_BeginScene(device);
8743     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8744     if(SUCCEEDED(hr)) {
8745         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8746         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8748         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8749         hr = IDirect3DDevice9_EndScene(device);
8750         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8751     }
8752
8753     /* This has to be pixel exact */
8754     color = getPixelColor(device, 319, 239);
8755     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8756     color = getPixelColor(device, 320, 239);
8757     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8758     color = getPixelColor(device, 319, 240);
8759     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8760     color = getPixelColor(device, 320, 240);
8761     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8762     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8763
8764     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8765                                              &surface, NULL);
8766     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8767     hr = IDirect3DDevice9_BeginScene(device);
8768     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8769     if(SUCCEEDED(hr)) {
8770         constant[2] = 16; constant[3] = 16;
8771         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8773         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8776         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8777         hr = IDirect3DDevice9_EndScene(device);
8778         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8779     }
8780     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8781     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8782
8783     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8784     color = *pos & 0x00ffffff;
8785     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8786     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8787     color = *pos & 0x00ffffff;
8788     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8789     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8790     color = *pos & 0x00ffffff;
8791     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8792     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8793     color = *pos & 0x00ffffff;
8794     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8795
8796     hr = IDirect3DSurface9_UnlockRect(surface);
8797     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8798
8799     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8800      * have full control over the multisampling setting inside this test
8801      */
8802     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8803     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8804     hr = IDirect3DDevice9_BeginScene(device);
8805     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8806     if(SUCCEEDED(hr)) {
8807         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8808         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8810         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_EndScene(device);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8813     }
8814     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8815     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8816
8817     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8818     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8819
8820     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8821     color = *pos & 0x00ffffff;
8822     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8823
8824     hr = IDirect3DSurface9_UnlockRect(surface);
8825     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8826
8827     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8828     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8829     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8830     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8831     IDirect3DPixelShader9_Release(shader);
8832     IDirect3DPixelShader9_Release(shader_frac);
8833     IDirect3DVertexShader9_Release(vshader);
8834     if(surface) IDirect3DSurface9_Release(surface);
8835     IDirect3DSurface9_Release(backbuffer);
8836 }
8837
8838 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8839 {
8840     D3DCOLOR color;
8841
8842     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8843     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8844     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8845     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8846     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8847
8848     ++r;
8849     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8850     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8851     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8852     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8853     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8854
8855     return TRUE;
8856 }
8857
8858 static void pointsize_test(IDirect3DDevice9 *device)
8859 {
8860     HRESULT hr;
8861     D3DCAPS9 caps;
8862     D3DMATRIX matrix;
8863     D3DMATRIX identity;
8864     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8865     DWORD color;
8866     IDirect3DSurface9 *rt, *backbuffer;
8867     IDirect3DTexture9 *tex1, *tex2;
8868     RECT rect = {0, 0, 128, 128};
8869     D3DLOCKED_RECT lr;
8870     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8871                                 0x00000000, 0x00000000};
8872     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8873                                 0x00000000, 0x0000ff00};
8874
8875     const float vertices[] = {
8876         64,     64,     0.1,
8877         128,    64,     0.1,
8878         192,    64,     0.1,
8879         256,    64,     0.1,
8880         320,    64,     0.1,
8881         384,    64,     0.1,
8882         448,    64,     0.1,
8883         512,    64,     0.1,
8884     };
8885
8886     /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */
8887     U(matrix).m[0][0] = 2.0/640.0; U(matrix).m[1][0] = 0.0;       U(matrix).m[2][0] = 0.0;   U(matrix).m[3][0] =-1.0;
8888     U(matrix).m[0][1] = 0.0;       U(matrix).m[1][1] =-2.0/480.0; U(matrix).m[2][1] = 0.0;   U(matrix).m[3][1] = 1.0;
8889     U(matrix).m[0][2] = 0.0;       U(matrix).m[1][2] = 0.0;       U(matrix).m[2][2] = 1.0;   U(matrix).m[3][2] = 0.0;
8890     U(matrix).m[0][3] = 0.0;       U(matrix).m[1][3] = 0.0;       U(matrix).m[2][3] = 0.0;   U(matrix).m[3][3] = 1.0;
8891
8892     U(identity).m[0][0] = 1.0;     U(identity).m[1][0] = 0.0;     U(identity).m[2][0] = 0.0; U(identity).m[3][0] = 0.0;
8893     U(identity).m[0][1] = 0.0;     U(identity).m[1][1] = 1.0;     U(identity).m[2][1] = 0.0; U(identity).m[3][1] = 0.0;
8894     U(identity).m[0][2] = 0.0;     U(identity).m[1][2] = 0.0;     U(identity).m[2][2] = 1.0; U(identity).m[3][2] = 0.0;
8895     U(identity).m[0][3] = 0.0;     U(identity).m[1][3] = 0.0;     U(identity).m[2][3] = 0.0; U(identity).m[3][3] = 1.0;
8896
8897     memset(&caps, 0, sizeof(caps));
8898     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8899     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8900     if(caps.MaxPointSize < 32.0) {
8901         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8902         return;
8903     }
8904
8905     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8906     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8907     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8908     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8910     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8911     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8912     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8913
8914     hr = IDirect3DDevice9_BeginScene(device);
8915     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8916     if (SUCCEEDED(hr))
8917     {
8918         ptsize = 15.0;
8919         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8920         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8921         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8922         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8923
8924         ptsize = 31.0;
8925         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8926         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8927         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8928         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8929
8930         ptsize = 30.75;
8931         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8932         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8933         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8934         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8935
8936         if (caps.MaxPointSize >= 63.0)
8937         {
8938             ptsize = 63.0;
8939             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8940             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8941             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8942             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8943
8944             ptsize = 62.75;
8945             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8946             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8947             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8948             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8949         }
8950
8951         ptsize = 1.0;
8952         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8953         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8955         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8956
8957         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8958         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8959         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8960         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8961
8962         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8963         ptsize = 15.0;
8964         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8965         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8966         ptsize = 1.0;
8967         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8968         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8970         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8971
8972         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8973         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8974
8975         /* pointsize < pointsize_min < pointsize_max?
8976          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8977         ptsize = 1.0;
8978         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8979         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8980         ptsize = 15.0;
8981         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8982         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8984         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8985
8986         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8987         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8988
8989         hr = IDirect3DDevice9_EndScene(device);
8990         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8991     }
8992
8993     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8994     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8995     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8996
8997     if (caps.MaxPointSize >= 63.0)
8998     {
8999         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9000         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9001     }
9002
9003     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9004     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9005     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9006     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9007     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9008
9009     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9010
9011     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9012      * generates texture coordinates for the point(result: Yes, it does)
9013      *
9014      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9015      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9016      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9017      */
9018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9020
9021     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9022     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9023     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9024     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9025     memset(&lr, 0, sizeof(lr));
9026     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9027     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9028     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9029     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9030     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9031     memset(&lr, 0, sizeof(lr));
9032     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9033     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9034     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9035     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9036     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9037     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9038     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9039     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9040     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9041     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9042     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9043     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9044     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9045     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9046     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9047     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9048     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9049     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9050     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9051
9052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9053     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9054     ptsize = 32.0;
9055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9057
9058     hr = IDirect3DDevice9_BeginScene(device);
9059     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9060     if(SUCCEEDED(hr))
9061     {
9062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9063         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9064         hr = IDirect3DDevice9_EndScene(device);
9065         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9066     }
9067
9068     color = getPixelColor(device, 64-4, 64-4);
9069     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9070     color = getPixelColor(device, 64-4, 64+4);
9071     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9072     color = getPixelColor(device, 64+4, 64+4);
9073     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9074     color = getPixelColor(device, 64+4, 64-4);
9075     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9076     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9077
9078     U(matrix).m[0][0] =  1.0f / 64.0f;
9079     U(matrix).m[1][1] = -1.0f / 64.0f;
9080     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9081     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9082
9083     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9084     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9085
9086     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9087             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9088     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9089
9090     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9091     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9092     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9093     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9094
9095     hr = IDirect3DDevice9_BeginScene(device);
9096     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9097     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9098     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9099     hr = IDirect3DDevice9_EndScene(device);
9100     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9101
9102     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9103     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9104     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9105     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9106     IDirect3DSurface9_Release(backbuffer);
9107     IDirect3DSurface9_Release(rt);
9108
9109     color = getPixelColor(device, 64-4, 64-4);
9110     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9111             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9112     color = getPixelColor(device, 64+4, 64-4);
9113     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9114             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9115     color = getPixelColor(device, 64-4, 64+4);
9116     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9117             "Expected color 0x00000000, got 0x%08x.\n", color);
9118     color = getPixelColor(device, 64+4, 64+4);
9119     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9120             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9121
9122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9123     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9124
9125     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9126     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9127     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9128     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9129     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9130     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9131     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9132     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9133     IDirect3DTexture9_Release(tex1);
9134     IDirect3DTexture9_Release(tex2);
9135
9136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9137     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9140     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9141     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9142 }
9143
9144 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9145 {
9146     static const DWORD vshader_code[] =
9147     {
9148         0xfffe0300,                                                             /* vs_3_0                     */
9149         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9150         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9151         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9152         0x0000ffff                                                              /* end                        */
9153     };
9154     static const DWORD pshader_code1[] =
9155     {
9156         0xffff0300,                                                             /* ps_3_0                     */
9157         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9158         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9159         0x0000ffff                                                              /* end                        */
9160     };
9161     static const DWORD pshader_code2[] =
9162     {
9163         0xffff0300,                                                             /* ps_3_0                     */
9164         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9165         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9166         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9167         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9168         0x0000ffff                                                              /* end                        */
9169     };
9170
9171     HRESULT hr;
9172     IDirect3DVertexShader9 *vs;
9173     IDirect3DPixelShader9 *ps1, *ps2;
9174     IDirect3DTexture9 *tex1, *tex2;
9175     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9176     D3DCAPS9 caps;
9177     DWORD color;
9178     UINT i, j;
9179     float quad[] = {
9180        -1.0,   -1.0,    0.1,
9181         1.0,   -1.0,    0.1,
9182        -1.0,    1.0,    0.1,
9183         1.0,    1.0,    0.1,
9184     };
9185     float texquad[] = {
9186        -1.0,   -1.0,    0.1,    0.0,    0.0,
9187         0.0,   -1.0,    0.1,    1.0,    0.0,
9188        -1.0,    1.0,    0.1,    0.0,    1.0,
9189         0.0,    1.0,    0.1,    1.0,    1.0,
9190
9191         0.0,   -1.0,    0.1,    0.0,    0.0,
9192         1.0,   -1.0,    0.1,    1.0,    0.0,
9193         0.0,    1.0,    0.1,    0.0,    1.0,
9194         1.0,    1.0,    0.1,    1.0,    1.0,
9195     };
9196
9197     memset(&caps, 0, sizeof(caps));
9198     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9199     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9200     if(caps.NumSimultaneousRTs < 2) {
9201         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9202         return;
9203     }
9204
9205     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9206     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9207
9208     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9209             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9210     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9211
9212     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9213             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9214     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9215     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9216             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9217     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9218     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9219     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9220     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9221     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9222     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9223     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9224
9225     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9226     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9227     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9228     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9229     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9230     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9231
9232     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9233     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9234     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9235     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9236     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9237     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9238     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9239     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9240
9241     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9242     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9243     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9244     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9245     color = getPixelColorFromSurface(readback, 8, 8);
9246     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9247             "Expected color 0x000000ff, got 0x%08x.\n", color);
9248     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9249     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9250     color = getPixelColorFromSurface(readback, 8, 8);
9251     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9252             "Expected color 0x000000ff, got 0x%08x.\n", color);
9253
9254     /* Render targets not written by the pixel shader should be unmodified. */
9255     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9256     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9257     hr = IDirect3DDevice9_BeginScene(device);
9258     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9259     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9260     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9261     hr = IDirect3DDevice9_EndScene(device);
9262     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9263     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9264     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9265     color = getPixelColorFromSurface(readback, 8, 8);
9266     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9267             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9268     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9269     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9270     for (i = 6; i < 10; ++i)
9271     {
9272         for (j = 6; j < 10; ++j)
9273         {
9274             color = getPixelColorFromSurface(readback, j, i);
9275             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9276                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9277         }
9278     }
9279
9280     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9281     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9282     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9283     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9284     color = getPixelColorFromSurface(readback, 8, 8);
9285     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9286             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9287     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9288     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9289     color = getPixelColorFromSurface(readback, 8, 8);
9290     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9291             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9292
9293     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9294     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9295
9296     hr = IDirect3DDevice9_BeginScene(device);
9297     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9298     if(SUCCEEDED(hr)) {
9299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9300         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9301
9302         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9303         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9304         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9305         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9306         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9307         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9308         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9310         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9311         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9312
9313         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9314         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9316         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9317
9318         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9319         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9320         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9321         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9322
9323         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9324         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9325
9326         hr = IDirect3DDevice9_EndScene(device);
9327         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9328     }
9329
9330     color = getPixelColor(device, 160, 240);
9331     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9332     color = getPixelColor(device, 480, 240);
9333     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9334     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9335
9336     IDirect3DPixelShader9_Release(ps2);
9337     IDirect3DPixelShader9_Release(ps1);
9338     IDirect3DVertexShader9_Release(vs);
9339     IDirect3DTexture9_Release(tex1);
9340     IDirect3DTexture9_Release(tex2);
9341     IDirect3DSurface9_Release(surf1);
9342     IDirect3DSurface9_Release(surf2);
9343     IDirect3DSurface9_Release(backbuf);
9344     IDirect3DSurface9_Release(readback);
9345 }
9346
9347 struct formats {
9348     const char *fmtName;
9349     D3DFORMAT textureFormat;
9350     DWORD resultColorBlending;
9351     DWORD resultColorNoBlending;
9352 };
9353
9354 static const struct formats test_formats[] = {
9355   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9356   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9357   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9358   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9359   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9360   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9361   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9362   { NULL, 0 }
9363 };
9364
9365 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9366 {
9367     HRESULT hr;
9368     IDirect3DTexture9 *offscreenTexture = NULL;
9369     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9370     IDirect3D9 *d3d = NULL;
9371     DWORD color;
9372     DWORD r0, g0, b0, r1, g1, b1;
9373     int fmt_index;
9374
9375     static const float quad[][5] = {
9376         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9377         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9378         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9379         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9380     };
9381
9382     /* Quad with R=0x10, G=0x20 */
9383     static const struct vertex quad1[] = {
9384         {-1.0f, -1.0f, 0.1f, 0x80102000},
9385         {-1.0f,  1.0f, 0.1f, 0x80102000},
9386         { 1.0f, -1.0f, 0.1f, 0x80102000},
9387         { 1.0f,  1.0f, 0.1f, 0x80102000},
9388     };
9389
9390     /* Quad with R=0x20, G=0x10 */
9391     static const struct vertex quad2[] = {
9392         {-1.0f, -1.0f, 0.1f, 0x80201000},
9393         {-1.0f,  1.0f, 0.1f, 0x80201000},
9394         { 1.0f, -1.0f, 0.1f, 0x80201000},
9395         { 1.0f,  1.0f, 0.1f, 0x80201000},
9396     };
9397
9398     IDirect3DDevice9_GetDirect3D(device, &d3d);
9399
9400     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9401     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9402     if(!backbuffer) {
9403         goto out;
9404     }
9405
9406     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9407     {
9408         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9409
9410         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9411                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9412         {
9413             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9414             continue;
9415         }
9416
9417         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9418         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9419
9420         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9421         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9422         if(!offscreenTexture) {
9423             continue;
9424         }
9425
9426         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9427         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9428         if(!offscreen) {
9429             continue;
9430         }
9431
9432         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9433         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9434
9435         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9436         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9437         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9438         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9439         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9440         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9441         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9442         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9443         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9444         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9445
9446         /* Below we will draw two quads with different colors and try to blend them together.
9447          * The result color is compared with the expected outcome.
9448          */
9449         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9450             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9451             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9452             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9453             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9454
9455             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9456             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9457
9458             /* Draw a quad using color 0x0010200 */
9459             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9460             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9461             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9462             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9463             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9464             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9465
9466             /* Draw a quad using color 0x0020100 */
9467             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9468             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9469             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9470             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9471             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9472             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9473
9474             /* We don't want to blend the result on the backbuffer */
9475             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9476             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9477
9478             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9479             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9480             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9481             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9482             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9483
9484             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9485             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9486
9487             /* This time with the texture */
9488             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9489             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9490
9491             IDirect3DDevice9_EndScene(device);
9492         }
9493
9494         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9495             /* Compare the color of the center quad with our expectation */
9496             color = getPixelColor(device, 320, 240);
9497             r0 = (color & 0x00ff0000) >> 16;
9498             g0 = (color & 0x0000ff00) >>  8;
9499             b0 = (color & 0x000000ff) >>  0;
9500
9501             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9502             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9503             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9504
9505             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9506                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9507                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9508                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9509         } else {
9510             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9511              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9512              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9513             color = getPixelColor(device, 320, 240);
9514             ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
9515         }
9516         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9517
9518         IDirect3DDevice9_SetTexture(device, 0, NULL);
9519         if(offscreenTexture) {
9520             IDirect3DTexture9_Release(offscreenTexture);
9521         }
9522         if(offscreen) {
9523             IDirect3DSurface9_Release(offscreen);
9524         }
9525     }
9526
9527 out:
9528     /* restore things */
9529     if(backbuffer) {
9530         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9531         IDirect3DSurface9_Release(backbuffer);
9532     }
9533 }
9534
9535 static void tssargtemp_test(IDirect3DDevice9 *device)
9536 {
9537     HRESULT hr;
9538     DWORD color;
9539     static const struct vertex quad[] = {
9540         {-1.0,     -1.0,    0.1,    0x00ff0000},
9541         { 1.0,     -1.0,    0.1,    0x00ff0000},
9542         {-1.0,      1.0,    0.1,    0x00ff0000},
9543         { 1.0,      1.0,    0.1,    0x00ff0000}
9544     };
9545     D3DCAPS9 caps;
9546
9547     memset(&caps, 0, sizeof(caps));
9548     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9549     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9550     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9551         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9552         return;
9553     }
9554
9555     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9556     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9557
9558     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9559     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9560     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9561     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9562
9563     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9564     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9565     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9566     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9567     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9568     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9569
9570     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9571     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9572     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9573     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9574     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9575     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9576
9577     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9579
9580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9582     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9583     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9584
9585     hr = IDirect3DDevice9_BeginScene(device);
9586     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9587     if(SUCCEEDED(hr)) {
9588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9589         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9590         hr = IDirect3DDevice9_EndScene(device);
9591         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9592     }
9593     color = getPixelColor(device, 320, 240);
9594     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9595     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9596
9597     /* Set stage 1 back to default */
9598     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9599     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9600     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9601     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9602     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9603     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9604     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9605     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9606     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9607     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9608 }
9609
9610 struct testdata
9611 {
9612     DWORD idxVertex; /* number of instances in the first stream */
9613     DWORD idxColor; /* number of instances in the second stream */
9614     DWORD idxInstance; /* should be 1 ?? */
9615     DWORD color1; /* color 1 instance */
9616     DWORD color2; /* color 2 instance */
9617     DWORD color3; /* color 3 instance */
9618     DWORD color4; /* color 4 instance */
9619     WORD strVertex; /* specify which stream to use 0-2*/
9620     WORD strColor;
9621     WORD strInstance;
9622 };
9623
9624 static const struct testdata testcases[]=
9625 {
9626     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9627     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9628     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9629     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9630     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9631     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9632     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9633     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9634     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9635     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9636     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9637     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9638     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9639     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9640 /*
9641     This draws one instance on some machines, no instance on others
9642     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9643 */
9644 /*
9645     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9646     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9647 */
9648 };
9649
9650 /* Drawing Indexed Geometry with instances*/
9651 static void stream_test(IDirect3DDevice9 *device)
9652 {
9653     IDirect3DVertexBuffer9 *vb = NULL;
9654     IDirect3DVertexBuffer9 *vb2 = NULL;
9655     IDirect3DVertexBuffer9 *vb3 = NULL;
9656     IDirect3DIndexBuffer9 *ib = NULL;
9657     IDirect3DVertexDeclaration9 *pDecl = NULL;
9658     IDirect3DVertexShader9 *shader = NULL;
9659     HRESULT hr;
9660     BYTE *data;
9661     DWORD color;
9662     DWORD ind;
9663     unsigned i;
9664
9665     const DWORD shader_code[] =
9666     {
9667         0xfffe0101,                                     /* vs_1_1 */
9668         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9669         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9670         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9671         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9672         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9673         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9674         0x0000ffff
9675     };
9676
9677     const float quad[][3] =
9678     {
9679         {-0.5f, -0.5f,  1.1f}, /*0 */
9680         {-0.5f,  0.5f,  1.1f}, /*1 */
9681         { 0.5f, -0.5f,  1.1f}, /*2 */
9682         { 0.5f,  0.5f,  1.1f}, /*3 */
9683     };
9684
9685     const float vertcolor[][4] =
9686     {
9687         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9688         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9689         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9690         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9691     };
9692
9693     /* 4 position for 4 instances */
9694     const float instancepos[][3] =
9695     {
9696         {-0.6f,-0.6f, 0.0f},
9697         { 0.6f,-0.6f, 0.0f},
9698         { 0.6f, 0.6f, 0.0f},
9699         {-0.6f, 0.6f, 0.0f},
9700     };
9701
9702     short indices[] = {0, 1, 2, 1, 2, 3};
9703
9704     D3DVERTEXELEMENT9 decl[] =
9705     {
9706         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9707         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9708         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9709         D3DDECL_END()
9710     };
9711
9712     /* set the default value because it isn't done in wine? */
9713     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9714     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9715
9716     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9717     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9718     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9719
9720     /* check wrong cases */
9721     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9722     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9723     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9724     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9725     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9726     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9727     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9728     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9729     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9730     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9731     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9732     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9733     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9734     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9735     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9736     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9737     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9738     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9739     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9740     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9741
9742     /* set the default value back */
9743     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9744     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9745
9746     /* create all VertexBuffers*/
9747     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9748     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9749     if(!vb) {
9750         skip("Failed to create a vertex buffer\n");
9751         return;
9752     }
9753     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9754     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9755     if(!vb2) {
9756         skip("Failed to create a vertex buffer\n");
9757         goto out;
9758     }
9759     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9760     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9761     if(!vb3) {
9762         skip("Failed to create a vertex buffer\n");
9763         goto out;
9764     }
9765
9766     /* create IndexBuffer*/
9767     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9768     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9769     if(!ib) {
9770         skip("Failed to create a index buffer\n");
9771         goto out;
9772     }
9773
9774     /* copy all Buffers (Vertex + Index)*/
9775     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9776     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9777     memcpy(data, quad, sizeof(quad));
9778     hr = IDirect3DVertexBuffer9_Unlock(vb);
9779     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9780     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9781     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9782     memcpy(data, vertcolor, sizeof(vertcolor));
9783     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9784     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9785     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9786     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9787     memcpy(data, instancepos, sizeof(instancepos));
9788     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9789     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9790     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9791     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9792     memcpy(data, indices, sizeof(indices));
9793     hr = IDirect3DIndexBuffer9_Unlock(ib);
9794     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9795
9796     /* create VertexShader */
9797     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9798     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9799     if(!shader) {
9800         skip("Failed to create a vetex shader\n");
9801         goto out;
9802     }
9803
9804     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9806
9807     hr = IDirect3DDevice9_SetIndices(device, ib);
9808     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9809
9810     /* run all tests */
9811     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9812     {
9813         struct testdata act = testcases[i];
9814         decl[0].Stream = act.strVertex;
9815         decl[1].Stream = act.strColor;
9816         decl[2].Stream = act.strInstance;
9817         /* create VertexDeclarations */
9818         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9819         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9820
9821         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9822         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9823
9824         hr = IDirect3DDevice9_BeginScene(device);
9825         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9826         if(SUCCEEDED(hr))
9827         {
9828             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9829             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9830
9831             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9832             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9833             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9834             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9835
9836             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9837             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9838             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9839             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9840
9841             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9842             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9843             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9844             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9845
9846             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9847             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9848             hr = IDirect3DDevice9_EndScene(device);
9849             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9850
9851             /* set all StreamSource && StreamSourceFreq back to default */
9852             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9853             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9854             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9855             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9856             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9857             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9858             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9859             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9860             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9861             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9862             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9863             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9864         }
9865
9866         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9867         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9868
9869         color = getPixelColor(device, 160, 360);
9870         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9871         color = getPixelColor(device, 480, 360);
9872         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9873         color = getPixelColor(device, 480, 120);
9874         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9875         color = getPixelColor(device, 160, 120);
9876         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9877
9878         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9879         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9880     }
9881
9882     hr = IDirect3DDevice9_SetIndices(device, NULL);
9883     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9884
9885 out:
9886     if(vb) IDirect3DVertexBuffer9_Release(vb);
9887     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9888     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9889     if(ib)IDirect3DIndexBuffer9_Release(ib);
9890     if(shader)IDirect3DVertexShader9_Release(shader);
9891 }
9892
9893 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9894     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9895     IDirect3DTexture9 *dsttex = NULL;
9896     HRESULT hr;
9897     DWORD color;
9898     D3DRECT r1 = {0,  0,  50,  50 };
9899     D3DRECT r2 = {50, 0,  100, 50 };
9900     D3DRECT r3 = {50, 50, 100, 100};
9901     D3DRECT r4 = {0,  50,  50, 100};
9902     const float quad[] = {
9903         -1.0,   -1.0,   0.1,    0.0,    0.0,
9904          1.0,   -1.0,   0.1,    1.0,    0.0,
9905         -1.0,    1.0,   0.1,    0.0,    1.0,
9906          1.0,    1.0,   0.1,    1.0,    1.0,
9907     };
9908
9909     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9910     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9911
9912     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9913     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9914     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9915     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9916
9917     if(!src || !dsttex) {
9918         skip("One or more test resources could not be created\n");
9919         goto cleanup;
9920     }
9921
9922     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9923     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9924
9925     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9926     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9927
9928     /* Clear the StretchRect destination for debugging */
9929     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9930     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9933
9934     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9935     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9936
9937     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9938     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9939     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9940     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9941     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9942     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9943     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9944     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9945
9946     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9947      * the target -> texture GL blit path
9948      */
9949     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9950     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9951     IDirect3DSurface9_Release(dst);
9952
9953     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9955
9956     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9957     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9958     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9959     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9961     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9964
9965     hr = IDirect3DDevice9_BeginScene(device);
9966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9967     if(SUCCEEDED(hr)) {
9968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9969         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9970         hr = IDirect3DDevice9_EndScene(device);
9971         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9972     }
9973
9974     color = getPixelColor(device, 160, 360);
9975     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9976     color = getPixelColor(device, 480, 360);
9977     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9978     color = getPixelColor(device, 480, 120);
9979     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9980     color = getPixelColor(device, 160, 120);
9981     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9982     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9983     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9984
9985     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9986     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9987     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9988     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9989
9990 cleanup:
9991     if(src) IDirect3DSurface9_Release(src);
9992     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9993     if(dsttex) IDirect3DTexture9_Release(dsttex);
9994 }
9995
9996 static void texop_test(IDirect3DDevice9 *device)
9997 {
9998     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9999     IDirect3DTexture9 *texture = NULL;
10000     D3DLOCKED_RECT locked_rect;
10001     D3DCOLOR color;
10002     D3DCAPS9 caps;
10003     HRESULT hr;
10004     unsigned i;
10005
10006     static const struct {
10007         float x, y, z;
10008         float s, t;
10009         D3DCOLOR diffuse;
10010     } quad[] = {
10011         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10012         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10013         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10014         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10015     };
10016
10017     static const D3DVERTEXELEMENT9 decl_elements[] = {
10018         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10019         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10020         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10021         D3DDECL_END()
10022     };
10023
10024     static const struct {
10025         D3DTEXTUREOP op;
10026         const char *name;
10027         DWORD caps_flag;
10028         D3DCOLOR result;
10029     } test_data[] = {
10030         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10031         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10032         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10033         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10034         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10035         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10036         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10037         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10038         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10039         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10040         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10041         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10042         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10043         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10044         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10045         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10046         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10047         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10048         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10049         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10050         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10051         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10052         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10053     };
10054
10055     memset(&caps, 0, sizeof(caps));
10056     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10057     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10058
10059     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10060     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10061     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10062     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10063
10064     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10065     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10066     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10067     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10068     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10069     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10070     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10071     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10072     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10073
10074     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10075     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10076     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10077     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10078     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10079     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10080
10081     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10082     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10083
10084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10085     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10086     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10087     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10089     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10090
10091     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10092     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10093
10094     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10095     {
10096         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10097         {
10098             skip("tex operation %s not supported\n", test_data[i].name);
10099             continue;
10100         }
10101
10102         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10103         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10104
10105         hr = IDirect3DDevice9_BeginScene(device);
10106         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10107
10108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10109         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10110
10111         hr = IDirect3DDevice9_EndScene(device);
10112         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10113
10114         color = getPixelColor(device, 320, 240);
10115         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10116                 test_data[i].name, color, test_data[i].result);
10117
10118         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10119         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10120     }
10121
10122     if (texture) IDirect3DTexture9_Release(texture);
10123     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10124 }
10125
10126 static void yuv_color_test(IDirect3DDevice9 *device) {
10127     HRESULT hr;
10128     IDirect3DSurface9 *surface = NULL, *target = NULL;
10129     unsigned int fmt, i;
10130     D3DFORMAT format;
10131     const char *fmt_string;
10132     D3DLOCKED_RECT lr;
10133     IDirect3D9 *d3d;
10134     HRESULT color;
10135     DWORD ref_color_left, ref_color_right;
10136
10137     struct {
10138         DWORD in;           /* The input color */
10139         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10140         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10141         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10142         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10143     } test_data[] = {
10144     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10145      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10146      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10147      * that
10148      */
10149       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10150       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10151       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10152       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10153       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10154       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10155       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10156       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10157       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10158       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10159       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10160       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10161       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10162       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10163
10164       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10165       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10166       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10167       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10168     };
10169
10170     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10171     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10172     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10173     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10174
10175     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10176     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10177
10178     for(fmt = 0; fmt < 2; fmt++) {
10179         if(fmt == 0) {
10180             format = D3DFMT_UYVY;
10181             fmt_string = "D3DFMT_UYVY";
10182         } else {
10183             format = D3DFMT_YUY2;
10184             fmt_string = "D3DFMT_YUY2";
10185         }
10186
10187         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10188                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10189                        */
10190         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10191                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10192             skip("%s is not supported\n", fmt_string);
10193             continue;
10194         }
10195
10196         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10197         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10198         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10199
10200         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10201             if(fmt == 0) {
10202                 ref_color_left = test_data[i].uyvy_left;
10203                 ref_color_right = test_data[i].uyvy_right;
10204             } else {
10205                 ref_color_left = test_data[i].yuy2_left;
10206                 ref_color_right = test_data[i].yuy2_right;
10207             }
10208
10209             memset(&lr, 0, sizeof(lr));
10210             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10211             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10212             *((DWORD *) lr.pBits) = test_data[i].in;
10213             hr = IDirect3DSurface9_UnlockRect(surface);
10214             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10215
10216             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10217             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10218             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10219             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10220
10221             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10222              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10223              * want to add tests for the filtered pixels as well.
10224              *
10225              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10226              * differently, so we need a max diff of 16
10227              */
10228             color = getPixelColor(device, 40, 240);
10229
10230             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10231              * where U != V. Skip the entire test if this bug in this case
10232              */
10233             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10234             {
10235                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10236                 IDirect3DSurface9_Release(surface);
10237                 goto out;
10238             }
10239
10240             ok(color_match(color, ref_color_left, 18),
10241                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10242                test_data[i].in, color, ref_color_left, fmt_string);
10243             color = getPixelColor(device, 600, 240);
10244             ok(color_match(color, ref_color_right, 18),
10245                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10246                test_data[i].in, color, ref_color_right, fmt_string);
10247             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10248             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10249         }
10250         IDirect3DSurface9_Release(surface);
10251     }
10252
10253 out:
10254     IDirect3DSurface9_Release(target);
10255     IDirect3D9_Release(d3d);
10256 }
10257
10258 static void texop_range_test(IDirect3DDevice9 *device)
10259 {
10260     static const struct {
10261         float x, y, z;
10262         D3DCOLOR diffuse;
10263     } quad[] = {
10264         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10265         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10266         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10267         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10268     };
10269     HRESULT hr;
10270     IDirect3DTexture9 *texture;
10271     D3DLOCKED_RECT locked_rect;
10272     D3DCAPS9 caps;
10273     DWORD color;
10274
10275     /* We need ADD and SUBTRACT operations */
10276     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10277     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10278     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10279         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10280         return;
10281     }
10282     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10283         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10284         return;
10285     }
10286
10287     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10288     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10289     /* Stage 1: result = diffuse(=1.0) + diffuse
10290      * stage 2: result = result - tfactor(= 0.5)
10291      */
10292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10293     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10294     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10295     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10296     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10297     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10298     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10299     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10300     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10301     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10302     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10303     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10304     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10305     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10306
10307     hr = IDirect3DDevice9_BeginScene(device);
10308     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10309     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10310     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10311     hr = IDirect3DDevice9_EndScene(device);
10312     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10313
10314     color = getPixelColor(device, 320, 240);
10315     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10316        color);
10317     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10318     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10319
10320     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10321     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10322     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10323     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10324     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10325     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10326     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10327     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10328     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10329
10330     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10331      * stage 2: result = result + diffuse(1.0)
10332      */
10333     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10334     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10335     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10336     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10337     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10338     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10339     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10340     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10341     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10342     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10343     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10344     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10345     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10346     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10347
10348     hr = IDirect3DDevice9_BeginScene(device);
10349     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10350     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10351     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10352     hr = IDirect3DDevice9_EndScene(device);
10353     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10354
10355     color = getPixelColor(device, 320, 240);
10356     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10357        color);
10358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10359     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10360
10361     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10362     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10363     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10364     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10365     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10366     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10367     IDirect3DTexture9_Release(texture);
10368 }
10369
10370 static void alphareplicate_test(IDirect3DDevice9 *device) {
10371     struct vertex quad[] = {
10372         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10373         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10374         { -1.0,     1.0,    0.1,    0x80ff00ff },
10375         {  1.0,     1.0,    0.1,    0x80ff00ff },
10376     };
10377     HRESULT hr;
10378     DWORD color;
10379
10380     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10381     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10382
10383     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10384     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10385
10386     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10387     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10388     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10389     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10390
10391     hr = IDirect3DDevice9_BeginScene(device);
10392     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10393     if(SUCCEEDED(hr)) {
10394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10396         hr = IDirect3DDevice9_EndScene(device);
10397         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10398     }
10399
10400     color = getPixelColor(device, 320, 240);
10401     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10402        color);
10403     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10404     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10405
10406     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10407     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10408
10409 }
10410
10411 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10412     HRESULT hr;
10413     D3DCAPS9 caps;
10414     DWORD color;
10415     struct vertex quad[] = {
10416         { -1.0,    -1.0,    0.1,    0x408080c0 },
10417         {  1.0,    -1.0,    0.1,    0x408080c0 },
10418         { -1.0,     1.0,    0.1,    0x408080c0 },
10419         {  1.0,     1.0,    0.1,    0x408080c0 },
10420     };
10421
10422     memset(&caps, 0, sizeof(caps));
10423     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10424     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10425     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10426         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10427         return;
10428     }
10429
10430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10432
10433     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10434     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10435
10436     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10437      * mov r0.a, diffuse.a
10438      * mov r0, r0.a
10439      *
10440      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10441      * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
10442      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10443      */
10444     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10445     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10446     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10447     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10448     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10449     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10450     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10451     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10452     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10453     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10454     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10455     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10456     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10457     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10458     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10459     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10460     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10461     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10462
10463     hr = IDirect3DDevice9_BeginScene(device);
10464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10465     if(SUCCEEDED(hr)) {
10466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10467         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10468         hr = IDirect3DDevice9_EndScene(device);
10469         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10470     }
10471
10472     color = getPixelColor(device, 320, 240);
10473     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10474        color);
10475     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10476     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10477
10478     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10479     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10480     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10481     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10482     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10483     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10484 }
10485
10486 static void zwriteenable_test(IDirect3DDevice9 *device) {
10487     HRESULT hr;
10488     DWORD color;
10489     struct vertex quad1[] = {
10490         { -1.0,  -1.0,  0.1,    0x00ff0000},
10491         { -1.0,   1.0,  0.1,    0x00ff0000},
10492         {  1.0,  -1.0,  0.1,    0x00ff0000},
10493         {  1.0,   1.0,  0.1,    0x00ff0000},
10494     };
10495     struct vertex quad2[] = {
10496         { -1.0,  -1.0,  0.9,    0x0000ff00},
10497         { -1.0,   1.0,  0.9,    0x0000ff00},
10498         {  1.0,  -1.0,  0.9,    0x0000ff00},
10499         {  1.0,   1.0,  0.9,    0x0000ff00},
10500     };
10501
10502     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10503     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10504
10505     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10506     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10511     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10512     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10513
10514     hr = IDirect3DDevice9_BeginScene(device);
10515     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10516     if(SUCCEEDED(hr)) {
10517         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10518          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10519          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10520          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10521          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10522          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10523          */
10524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10525         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10526         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10527         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10528         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10529         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10530
10531         hr = IDirect3DDevice9_EndScene(device);
10532         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10533     }
10534
10535     color = getPixelColor(device, 320, 240);
10536     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10537        color);
10538     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10539     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10540
10541     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10542     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10543 }
10544
10545 static void alphatest_test(IDirect3DDevice9 *device) {
10546 #define ALPHATEST_PASSED 0x0000ff00
10547 #define ALPHATEST_FAILED 0x00ff0000
10548     struct {
10549         D3DCMPFUNC  func;
10550         DWORD       color_less;
10551         DWORD       color_equal;
10552         DWORD       color_greater;
10553     } testdata[] = {
10554         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10555         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10556         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10557         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10558         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10559         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10560         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10561         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10562     };
10563     unsigned int i, j;
10564     HRESULT hr;
10565     DWORD color;
10566     struct vertex quad[] = {
10567         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10568         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10569         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10570         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10571     };
10572     D3DCAPS9 caps;
10573
10574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10576     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10577     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10578
10579     for(j = 0; j < 2; j++) {
10580         if(j == 1) {
10581             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10582              * the alpha test either for performance reasons(floating point RTs) or to work
10583              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10584              * codepath for ffp and shader in this case, and the test should cover both
10585              */
10586             IDirect3DPixelShader9 *ps;
10587             DWORD shader_code[] = {
10588                 0xffff0101,                                 /* ps_1_1           */
10589                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10590                 0x0000ffff                                  /* end              */
10591             };
10592             memset(&caps, 0, sizeof(caps));
10593             hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10594             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10595             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10596                 break;
10597             }
10598
10599             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10600             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10601             hr = IDirect3DDevice9_SetPixelShader(device, ps);
10602             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10603             IDirect3DPixelShader9_Release(ps);
10604         }
10605
10606         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10607             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10608             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10609
10610             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10611             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10612             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10613             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10614             hr = IDirect3DDevice9_BeginScene(device);
10615             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10616             if(SUCCEEDED(hr)) {
10617                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10618                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10619                 hr = IDirect3DDevice9_EndScene(device);
10620                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10621             }
10622             color = getPixelColor(device, 320, 240);
10623             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10624             color, testdata[i].color_less, testdata[i].func);
10625             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10626             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10627
10628             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10629             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10630             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10631             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10632             hr = IDirect3DDevice9_BeginScene(device);
10633             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10634             if(SUCCEEDED(hr)) {
10635                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10636                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10637                 hr = IDirect3DDevice9_EndScene(device);
10638                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10639             }
10640             color = getPixelColor(device, 320, 240);
10641             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10642             color, testdata[i].color_equal, testdata[i].func);
10643             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10644             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10645
10646             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10647             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10648             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10649             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10650             hr = IDirect3DDevice9_BeginScene(device);
10651             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10652             if(SUCCEEDED(hr)) {
10653                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10654                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10655                 hr = IDirect3DDevice9_EndScene(device);
10656                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10657             }
10658             color = getPixelColor(device, 320, 240);
10659             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10660             color, testdata[i].color_greater, testdata[i].func);
10661             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10662             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10663         }
10664     }
10665
10666     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10667     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10668     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10669     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10670 }
10671
10672 static void sincos_test(IDirect3DDevice9 *device) {
10673     const DWORD sin_shader_code[] = {
10674         0xfffe0200,                                                                 /* vs_2_0                       */
10675         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10676         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10677         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10678         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10679         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10680         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10681         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10682         0x0000ffff                                                                  /* end                          */
10683     };
10684     const DWORD cos_shader_code[] = {
10685         0xfffe0200,                                                                 /* vs_2_0                       */
10686         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10687         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10688         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10689         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10690         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10691         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10692         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10693         0x0000ffff                                                                  /* end                          */
10694     };
10695     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10696     HRESULT hr;
10697     struct {
10698         float x, y, z;
10699     } data[1280];
10700     unsigned int i;
10701     float sincosc1[4] = {D3DSINCOSCONST1};
10702     float sincosc2[4] = {D3DSINCOSCONST2};
10703
10704     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10705     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10706
10707     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10708     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10709     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10710     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10711     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10712     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10713     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10714     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10715     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10716     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10717
10718     /* Generate a point from -1 to 1 every 0.5 pixels */
10719     for(i = 0; i < 1280; i++) {
10720         data[i].x = (-640.0 + i) / 640.0;
10721         data[i].y = 0.0;
10722         data[i].z = 0.1;
10723     }
10724
10725     hr = IDirect3DDevice9_BeginScene(device);
10726     if(SUCCEEDED(hr)) {
10727         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10728         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10729         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10730         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10731
10732         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10733         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10735         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10736
10737         hr = IDirect3DDevice9_EndScene(device);
10738         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10739     }
10740     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10741     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10742     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10743
10744     IDirect3DDevice9_SetVertexShader(device, NULL);
10745     IDirect3DVertexShader9_Release(sin_shader);
10746     IDirect3DVertexShader9_Release(cos_shader);
10747 }
10748
10749 static void loop_index_test(IDirect3DDevice9 *device) {
10750     const DWORD shader_code[] = {
10751         0xfffe0200,                                                 /* vs_2_0                   */
10752         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10753         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10754         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10755         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10756         0x0000001d,                                                 /* endloop                  */
10757         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10758         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10759         0x0000ffff                                                  /* END                      */
10760     };
10761     IDirect3DVertexShader9 *shader;
10762     HRESULT hr;
10763     DWORD color;
10764     const float quad[] = {
10765         -1.0,   -1.0,   0.1,
10766          1.0,   -1.0,   0.1,
10767         -1.0,    1.0,   0.1,
10768          1.0,    1.0,   0.1
10769     };
10770     const float zero[4] = {0, 0, 0, 0};
10771     const float one[4] = {1, 1, 1, 1};
10772     int i0[4] = {2, 10, -3, 0};
10773     float values[4];
10774
10775     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10776     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10777     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10778     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10779     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10780     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10781     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10782     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10783
10784     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10785     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10786     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10787     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10788     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10789     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10790     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10791     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10792     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10793     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10794     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10795     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10796     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10797     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10798     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10799     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10800     values[0] = 1.0;
10801     values[1] = 1.0;
10802     values[2] = 0.0;
10803     values[3] = 0.0;
10804     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10806     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10807     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10808     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10809     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10810     values[0] = -1.0;
10811     values[1] = 0.0;
10812     values[2] = 0.0;
10813     values[3] = 0.0;
10814     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10815     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10816     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10817     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10818     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10819     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10820     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10821     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10822     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10823     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10824
10825     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10826     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10827
10828     hr = IDirect3DDevice9_BeginScene(device);
10829     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10830     if(SUCCEEDED(hr))
10831     {
10832         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10833         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10834         hr = IDirect3DDevice9_EndScene(device);
10835         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10836     }
10837     color = getPixelColor(device, 320, 240);
10838     ok(color_match(color, 0x0000ff00, 1),
10839        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10840     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10841     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10842
10843     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10844     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10845     IDirect3DVertexShader9_Release(shader);
10846 }
10847
10848 static void sgn_test(IDirect3DDevice9 *device) {
10849     const DWORD shader_code[] = {
10850         0xfffe0200,                                                             /* vs_2_0                       */
10851         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10852         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10853         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10854         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10855         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10856         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10857         0x0000ffff                                                              /* end                          */
10858     };
10859     IDirect3DVertexShader9 *shader;
10860     HRESULT hr;
10861     DWORD color;
10862     const float quad[] = {
10863         -1.0,   -1.0,   0.1,
10864          1.0,   -1.0,   0.1,
10865         -1.0,    1.0,   0.1,
10866          1.0,    1.0,   0.1
10867     };
10868
10869     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10870     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10871     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10872     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10873     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10874     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10875     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10876     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10877
10878     hr = IDirect3DDevice9_BeginScene(device);
10879     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10880     if(SUCCEEDED(hr))
10881     {
10882         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10883         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10884         hr = IDirect3DDevice9_EndScene(device);
10885         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10886     }
10887     color = getPixelColor(device, 320, 240);
10888     ok(color_match(color, 0x008000ff, 1),
10889        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10891     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10892
10893     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10894     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10895     IDirect3DVertexShader9_Release(shader);
10896 }
10897
10898 static void viewport_test(IDirect3DDevice9 *device) {
10899     HRESULT hr;
10900     DWORD color;
10901     D3DVIEWPORT9 vp, old_vp;
10902     BOOL draw_failed = TRUE;
10903     const float quad[] =
10904     {
10905         -0.5,   -0.5,   0.1,
10906          0.5,   -0.5,   0.1,
10907         -0.5,    0.5,   0.1,
10908          0.5,    0.5,   0.1
10909     };
10910
10911     memset(&old_vp, 0, sizeof(old_vp));
10912     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10913     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10914
10915     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10916     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10917
10918     /* Test a viewport with Width and Height bigger than the surface dimensions
10919      *
10920      * TODO: Test Width < surface.width, but X + Width > surface.width
10921      * TODO: Test Width < surface.width, what happens with the height?
10922      *
10923      * The expected behavior is that the viewport behaves like the "default"
10924      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10925      * MinZ = 0.0, MaxZ = 1.0.
10926      *
10927      * Starting with Windows 7 the behavior among driver versions is not
10928      * consistent. The SetViewport call is accepted on all drivers. Some
10929      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10930      * nvidia drivers draw, but use the actual values in the viewport and only
10931      * display the upper left part on the surface.
10932      */
10933     memset(&vp, 0, sizeof(vp));
10934     vp.X = 0;
10935     vp.Y = 0;
10936     vp.Width = 10000;
10937     vp.Height = 10000;
10938     vp.MinZ = 0.0;
10939     vp.MaxZ = 0.0;
10940     hr = IDirect3DDevice9_SetViewport(device, &vp);
10941     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10942
10943     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10944     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10945     hr = IDirect3DDevice9_BeginScene(device);
10946     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10947     if(SUCCEEDED(hr))
10948     {
10949         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10950         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10951         draw_failed = FAILED(hr);
10952         hr = IDirect3DDevice9_EndScene(device);
10953         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10954     }
10955
10956     if(!draw_failed)
10957     {
10958         color = getPixelColor(device, 158, 118);
10959         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10960         color = getPixelColor(device, 162, 118);
10961         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10962         color = getPixelColor(device, 158, 122);
10963         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10964         color = getPixelColor(device, 162, 122);
10965         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10966
10967         color = getPixelColor(device, 478, 358);
10968         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10969         color = getPixelColor(device, 482, 358);
10970         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10971         color = getPixelColor(device, 478, 362);
10972         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10973         color = getPixelColor(device, 482, 362);
10974         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10975     }
10976
10977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10979
10980     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10981     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10982 }
10983
10984 /* This test tests depth clamping / clipping behaviour:
10985  *   - With software vertex processing, depth values are clamped to the
10986  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10987  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10988  *     same as regular vertices here.
10989  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10990  *     Normal vertices are always clipped. Pretransformed vertices are
10991  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10992  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10993  */
10994 static void depth_clamp_test(IDirect3DDevice9 *device)
10995 {
10996     const struct tvertex quad1[] =
10997     {
10998         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10999         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11000         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11001         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11002     };
11003     const struct tvertex quad2[] =
11004     {
11005         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11006         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11007         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11008         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11009     };
11010     const struct tvertex quad3[] =
11011     {
11012         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11013         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11014         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11015         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11016     };
11017     const struct tvertex quad4[] =
11018     {
11019         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11020         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11021         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11022         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11023     };
11024     const struct vertex quad5[] =
11025     {
11026         { -0.5f,   0.5f, 10.0f,       0xff14f914},
11027         {  0.5f,   0.5f, 10.0f,       0xff14f914},
11028         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
11029         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
11030     };
11031     const struct vertex quad6[] =
11032     {
11033         { -1.0f,   0.5f, 10.0f,      0xfff91414},
11034         {  1.0f,   0.5f, 10.0f,      0xfff91414},
11035         { -1.0f,  0.25f, 10.0f,      0xfff91414},
11036         {  1.0f,  0.25f, 10.0f,      0xfff91414},
11037     };
11038
11039     D3DVIEWPORT9 vp;
11040     D3DCOLOR color;
11041     D3DCAPS9 caps;
11042     HRESULT hr;
11043
11044     vp.X = 0;
11045     vp.Y = 0;
11046     vp.Width = 640;
11047     vp.Height = 480;
11048     vp.MinZ = 0.0;
11049     vp.MaxZ = 7.5;
11050
11051     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11052     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11053
11054     hr = IDirect3DDevice9_SetViewport(device, &vp);
11055     if(FAILED(hr))
11056     {
11057         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11058          * the tests because the 7.5 is just intended to show that it doesn't have
11059          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11060          * viewport and continue.
11061          */
11062         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11063         vp.MaxZ = 1.0;
11064         hr = IDirect3DDevice9_SetViewport(device, &vp);
11065     }
11066     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11067
11068     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11069     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11070
11071     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11072     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11074     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11076     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11078     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11079
11080     hr = IDirect3DDevice9_BeginScene(device);
11081     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11082
11083     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11084     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11085
11086     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11087     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11088     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11089     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11090
11091     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11092     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11093
11094     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11095     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11096     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11097     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11098
11099     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11100     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11101
11102     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11103     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11104
11105     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11106     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11107
11108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11109     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11110
11111     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11112     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11113
11114     hr = IDirect3DDevice9_EndScene(device);
11115     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11116
11117     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11118     {
11119         color = getPixelColor(device, 75, 75);
11120         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11121         color = getPixelColor(device, 150, 150);
11122         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11123         color = getPixelColor(device, 320, 240);
11124         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11125         color = getPixelColor(device, 320, 330);
11126         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11127         color = getPixelColor(device, 320, 330);
11128         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11129     }
11130     else
11131     {
11132         color = getPixelColor(device, 75, 75);
11133         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11134         color = getPixelColor(device, 150, 150);
11135         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11136         color = getPixelColor(device, 320, 240);
11137         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11138         color = getPixelColor(device, 320, 330);
11139         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11140         color = getPixelColor(device, 320, 330);
11141         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11142     }
11143
11144     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11145     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11146
11147     vp.MinZ = 0.0;
11148     vp.MaxZ = 1.0;
11149     hr = IDirect3DDevice9_SetViewport(device, &vp);
11150     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11151 }
11152
11153 static void depth_bounds_test(IDirect3DDevice9 *device)
11154 {
11155     const struct tvertex quad1[] =
11156     {
11157         {    0,    0, 0.0f, 1, 0xfff9e814},
11158         {  640,    0, 0.0f, 1, 0xfff9e814},
11159         {    0,  480, 1.0f, 1, 0xfff9e814},
11160         {  640,  480, 1.0f, 1, 0xfff9e814},
11161     };
11162     const struct tvertex quad2[] =
11163     {
11164         {    0,    0,  0.6f, 1, 0xff002b7f},
11165         {  640,    0,  0.6f, 1, 0xff002b7f},
11166         {    0,  480,  0.6f, 1, 0xff002b7f},
11167         {  640,  480,  0.6f, 1, 0xff002b7f},
11168     };
11169     const struct tvertex quad3[] =
11170     {
11171         {    0,  100, 0.6f, 1, 0xfff91414},
11172         {  640,  100, 0.6f, 1, 0xfff91414},
11173         {    0,  160, 0.6f, 1, 0xfff91414},
11174         {  640,  160, 0.6f, 1, 0xfff91414},
11175     };
11176
11177     union {
11178         DWORD d;
11179         float f;
11180     } tmpvalue;
11181
11182     IDirect3D9 *d3d = NULL;
11183     IDirect3DSurface9 *offscreen_surface = NULL;
11184     D3DCOLOR color;
11185     HRESULT hr;
11186
11187     IDirect3DDevice9_GetDirect3D(device, &d3d);
11188     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11189             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11190         skip("No NVDB (depth bounds test) support\n");
11191         IDirect3D9_Release(d3d);
11192         return;
11193     }
11194     IDirect3D9_Release(d3d);
11195
11196     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11197             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11198     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11199     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11200
11201     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11202     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11203
11204     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11205     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11207     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11208     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11209     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11210     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11211     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11212
11213
11214     hr = IDirect3DDevice9_BeginScene(device);
11215     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11216
11217     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11218     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11219
11220     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11221     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11222
11223     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11224     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11225
11226     tmpvalue.f = 0.625;
11227     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11228     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11229
11230     tmpvalue.f = 0.75;
11231     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11232     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11233
11234     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11235     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11236
11237     tmpvalue.f = 0.75;
11238     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11239     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11240
11241     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11242     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11243
11244     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11245     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11246
11247     hr = IDirect3DDevice9_EndScene(device);
11248     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11249
11250     color = getPixelColor(device, 150, 130);
11251     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11252     color = getPixelColor(device, 150, 200);
11253     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11254     color = getPixelColor(device, 150, 300-5);
11255     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11256     color = getPixelColor(device, 150, 300+5);
11257     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11258     color = getPixelColor(device, 150, 330);
11259     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11260     color = getPixelColor(device, 150, 360-5);
11261     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11262     color = getPixelColor(device, 150, 360+5);
11263     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11264
11265     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11266     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11267 }
11268
11269 static void depth_buffer_test(IDirect3DDevice9 *device)
11270 {
11271     static const struct vertex quad1[] =
11272     {
11273         { -1.0,  1.0, 0.33f, 0xff00ff00},
11274         {  1.0,  1.0, 0.33f, 0xff00ff00},
11275         { -1.0, -1.0, 0.33f, 0xff00ff00},
11276         {  1.0, -1.0, 0.33f, 0xff00ff00},
11277     };
11278     static const struct vertex quad2[] =
11279     {
11280         { -1.0,  1.0, 0.50f, 0xffff00ff},
11281         {  1.0,  1.0, 0.50f, 0xffff00ff},
11282         { -1.0, -1.0, 0.50f, 0xffff00ff},
11283         {  1.0, -1.0, 0.50f, 0xffff00ff},
11284     };
11285     static const struct vertex quad3[] =
11286     {
11287         { -1.0,  1.0, 0.66f, 0xffff0000},
11288         {  1.0,  1.0, 0.66f, 0xffff0000},
11289         { -1.0, -1.0, 0.66f, 0xffff0000},
11290         {  1.0, -1.0, 0.66f, 0xffff0000},
11291     };
11292     static const DWORD expected_colors[4][4] =
11293     {
11294         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11295         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11296         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11297         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11298     };
11299
11300     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11301     unsigned int i, j;
11302     D3DVIEWPORT9 vp;
11303     D3DCOLOR color;
11304     HRESULT hr;
11305
11306     vp.X = 0;
11307     vp.Y = 0;
11308     vp.Width = 640;
11309     vp.Height = 480;
11310     vp.MinZ = 0.0;
11311     vp.MaxZ = 1.0;
11312
11313     hr = IDirect3DDevice9_SetViewport(device, &vp);
11314     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11315
11316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11317     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11319     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11321     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11323     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11324     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11325     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11326
11327     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11328     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11329     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11330             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11331     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11332     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11333             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11334     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11335     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11336             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11337     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11338
11339     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11340     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11341     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11342     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11343
11344     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11345     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11346     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11347     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11348
11349     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11350     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11351     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11352     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11353
11354     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11355     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11356     hr = IDirect3DDevice9_BeginScene(device);
11357     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11358     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11359     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11360     hr = IDirect3DDevice9_EndScene(device);
11361     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11362
11363     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11364     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11365
11366     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11367     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11368
11369     hr = IDirect3DDevice9_BeginScene(device);
11370     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11371     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11372     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11373     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11374     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11375     hr = IDirect3DDevice9_EndScene(device);
11376     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11377
11378     for (i = 0; i < 4; ++i)
11379     {
11380         for (j = 0; j < 4; ++j)
11381         {
11382             unsigned int x = 80 * ((2 * j) + 1);
11383             unsigned int y = 60 * ((2 * i) + 1);
11384             color = getPixelColor(device, x, y);
11385             ok(color_match(color, expected_colors[i][j], 0),
11386                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11387         }
11388     }
11389
11390     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11391     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11392
11393     IDirect3DSurface9_Release(backbuffer);
11394     IDirect3DSurface9_Release(rt3);
11395     IDirect3DSurface9_Release(rt2);
11396     IDirect3DSurface9_Release(rt1);
11397 }
11398
11399 /* Test that partial depth copies work the way they're supposed to. The clear
11400  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11401  * the following draw should only copy back the part that was modified. */
11402 static void depth_buffer2_test(IDirect3DDevice9 *device)
11403 {
11404     static const struct vertex quad[] =
11405     {
11406         { -1.0,  1.0, 0.66f, 0xffff0000},
11407         {  1.0,  1.0, 0.66f, 0xffff0000},
11408         { -1.0, -1.0, 0.66f, 0xffff0000},
11409         {  1.0, -1.0, 0.66f, 0xffff0000},
11410     };
11411
11412     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11413     unsigned int i, j;
11414     D3DVIEWPORT9 vp;
11415     D3DCOLOR color;
11416     HRESULT hr;
11417
11418     vp.X = 0;
11419     vp.Y = 0;
11420     vp.Width = 640;
11421     vp.Height = 480;
11422     vp.MinZ = 0.0;
11423     vp.MaxZ = 1.0;
11424
11425     hr = IDirect3DDevice9_SetViewport(device, &vp);
11426     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11427
11428     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11429     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11430     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11431     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11432     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11433     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11434     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11435     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11436     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11437     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11438
11439     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11440             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11441     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11442     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11443             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11444     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11445     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11446     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11447
11448     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11449     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11450     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11451     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11452
11453     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11454     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11456     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11457
11458     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11459     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11460     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11461     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11462
11463     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11464     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11465
11466     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11467     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11468
11469     hr = IDirect3DDevice9_BeginScene(device);
11470     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11471     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11472     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11473     hr = IDirect3DDevice9_EndScene(device);
11474     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11475
11476     for (i = 0; i < 4; ++i)
11477     {
11478         for (j = 0; j < 4; ++j)
11479         {
11480             unsigned int x = 80 * ((2 * j) + 1);
11481             unsigned int y = 60 * ((2 * i) + 1);
11482             color = getPixelColor(device, x, y);
11483             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11484                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11485         }
11486     }
11487
11488     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11489     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11490
11491     IDirect3DSurface9_Release(backbuffer);
11492     IDirect3DSurface9_Release(rt2);
11493     IDirect3DSurface9_Release(rt1);
11494 }
11495
11496 static void depth_blit_test(IDirect3DDevice9 *device)
11497 {
11498     static const struct vertex quad1[] =
11499     {
11500         { -1.0,  1.0, 0.50f, 0xff00ff00},
11501         {  1.0,  1.0, 0.50f, 0xff00ff00},
11502         { -1.0, -1.0, 0.50f, 0xff00ff00},
11503         {  1.0, -1.0, 0.50f, 0xff00ff00},
11504     };
11505     static const struct vertex quad2[] =
11506     {
11507         { -1.0,  1.0, 0.66f, 0xff0000ff},
11508         {  1.0,  1.0, 0.66f, 0xff0000ff},
11509         { -1.0, -1.0, 0.66f, 0xff0000ff},
11510         {  1.0, -1.0, 0.66f, 0xff0000ff},
11511     };
11512     static const DWORD expected_colors[4][4] =
11513     {
11514         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11515         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11516         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11517         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11518     };
11519
11520     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11521     RECT src_rect, dst_rect;
11522     unsigned int i, j;
11523     D3DVIEWPORT9 vp;
11524     D3DCOLOR color;
11525     HRESULT hr;
11526
11527     vp.X = 0;
11528     vp.Y = 0;
11529     vp.Width = 640;
11530     vp.Height = 480;
11531     vp.MinZ = 0.0;
11532     vp.MaxZ = 1.0;
11533
11534     hr = IDirect3DDevice9_SetViewport(device, &vp);
11535     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11536
11537     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11538     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11539     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11540     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11541     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11542     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11543     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11544     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11545     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11546     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11547
11548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11549     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11551     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11552     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11553     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11554     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11555     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11556
11557     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11558     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11559     SetRect(&dst_rect, 0, 0, 480, 360);
11560     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11561     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11562     SetRect(&dst_rect, 0, 0, 320, 240);
11563     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11564     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11565
11566     /* Partial blit. */
11567     SetRect(&src_rect, 0, 0, 320, 240);
11568     SetRect(&dst_rect, 0, 0, 320, 240);
11569     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11570     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11571     /* Flipped. */
11572     SetRect(&src_rect, 0, 0, 640, 480);
11573     SetRect(&dst_rect, 0, 480, 640, 0);
11574     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11575     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11576     /* Full, explicit. */
11577     SetRect(&src_rect, 0, 0, 640, 480);
11578     SetRect(&dst_rect, 0, 0, 640, 480);
11579     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11580     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11581     /* Filtered blit. */
11582     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11583     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11584     /* Depth -> color blit.*/
11585     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11586     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11587     IDirect3DSurface9_Release(backbuffer);
11588     /* Full surface, different sizes */
11589     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11590     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11591     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11592     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11593
11594     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11595     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11596     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11597     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11598     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11599     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11600
11601     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11602     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11603     hr = IDirect3DDevice9_BeginScene(device);
11604     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11605     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11606     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11607     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11608     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11609     hr = IDirect3DDevice9_EndScene(device);
11610     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11611
11612     for (i = 0; i < 4; ++i)
11613     {
11614         for (j = 0; j < 4; ++j)
11615         {
11616             unsigned int x = 80 * ((2 * j) + 1);
11617             unsigned int y = 60 * ((2 * i) + 1);
11618             color = getPixelColor(device, x, y);
11619             ok(color_match(color, expected_colors[i][j], 0),
11620                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11621         }
11622     }
11623
11624     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11625     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11626
11627     IDirect3DSurface9_Release(ds3);
11628     IDirect3DSurface9_Release(ds2);
11629     IDirect3DSurface9_Release(ds1);
11630 }
11631
11632 static void intz_test(IDirect3DDevice9 *device)
11633 {
11634     static const DWORD ps_code[] =
11635     {
11636         0xffff0200,                                                             /* ps_2_0                       */
11637         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11638         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11639         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11640         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11641         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11642         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11643         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11644         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11645         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11646         0x0000ffff,                                                             /* end                          */
11647     };
11648     struct
11649     {
11650         float x, y, z;
11651         float s, t, p, q;
11652     }
11653     quad[] =
11654     {
11655         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11656         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11657         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11658         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11659     },
11660     half_quad_1[] =
11661     {
11662         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11663         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11664         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11665         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11666     },
11667     half_quad_2[] =
11668     {
11669         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11670         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11671         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11672         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11673     };
11674     struct
11675     {
11676         UINT x, y;
11677         D3DCOLOR color;
11678     }
11679     expected_colors[] =
11680     {
11681         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11682         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11683         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11684         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11685         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11686         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11687         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11688         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11689     };
11690
11691     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11692     IDirect3DTexture9 *texture;
11693     IDirect3DPixelShader9 *ps;
11694     IDirect3DSurface9 *ds;
11695     IDirect3D9 *d3d9;
11696     D3DCAPS9 caps;
11697     HRESULT hr;
11698     UINT i;
11699
11700     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11701     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11702     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11703     {
11704         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11705         return;
11706     }
11707     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11708     {
11709         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11710         return;
11711     }
11712
11713     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11714     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11715
11716     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11717             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11718     if (FAILED(hr))
11719     {
11720         skip("No INTZ support, skipping INTZ test.\n");
11721         return;
11722     }
11723
11724     IDirect3D9_Release(d3d9);
11725
11726     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11727     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11728     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11729     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11730
11731     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11732             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11733     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11734     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11735             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11736     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11737     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11738     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11739
11740     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11741     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11742     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11743     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11744     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11745     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11746     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11747     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11748     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11749     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11750
11751     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11752     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11753     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11754     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11755     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11756     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11757     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11758     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11759     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11760     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11761
11762     /* Render offscreen, using the INTZ texture as depth buffer */
11763     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11764     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11765     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11766     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11767     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11768     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11769     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11770     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11771
11772     /* Setup the depth/stencil surface. */
11773     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11774     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11775
11776     hr = IDirect3DDevice9_BeginScene(device);
11777     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11778     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11779     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11780     hr = IDirect3DDevice9_EndScene(device);
11781     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11782
11783     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11784     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11785     IDirect3DSurface9_Release(ds);
11786     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11787     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11788     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11789     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11790     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11791     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11792
11793     /* Read the depth values back. */
11794     hr = IDirect3DDevice9_BeginScene(device);
11795     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11796     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11797     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11798     hr = IDirect3DDevice9_EndScene(device);
11799     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11800
11801     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11802     {
11803         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11804         ok(color_match(color, expected_colors[i].color, 1),
11805                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11806                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11807     }
11808
11809     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11810     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11811
11812     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11813     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11814     IDirect3DTexture9_Release(texture);
11815
11816     /* Render onscreen while using the INTZ texture as depth buffer */
11817     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11818             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11819     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11820     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11821     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11822     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11823     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11824     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11825
11826     /* Setup the depth/stencil surface. */
11827     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11828     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11829
11830     hr = IDirect3DDevice9_BeginScene(device);
11831     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11832     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11833     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11834     hr = IDirect3DDevice9_EndScene(device);
11835     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11836
11837     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11838     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11839     IDirect3DSurface9_Release(ds);
11840     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11841     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11842     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11843     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11844
11845     /* Read the depth values back. */
11846     hr = IDirect3DDevice9_BeginScene(device);
11847     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11848     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11849     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11850     hr = IDirect3DDevice9_EndScene(device);
11851     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11852
11853     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11854     {
11855         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11856         ok(color_match(color, expected_colors[i].color, 1),
11857                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11858                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11859     }
11860
11861     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11862     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11863
11864     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11865     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11866     IDirect3DTexture9_Release(texture);
11867
11868     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11869     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11870             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11871     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11872     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11873
11874     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11875     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11876     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11877     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11878     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11879     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11880
11881     /* Setup the depth/stencil surface. */
11882     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11883     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11884
11885     hr = IDirect3DDevice9_BeginScene(device);
11886     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11887     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11888     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11889     hr = IDirect3DDevice9_EndScene(device);
11890     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11891
11892     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11893     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11894
11895     hr = IDirect3DDevice9_BeginScene(device);
11896     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11897     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11898     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11899     hr = IDirect3DDevice9_EndScene(device);
11900     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11901
11902     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11903     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11904     IDirect3DSurface9_Release(ds);
11905     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11906     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11907     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11908     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11909
11910     /* Read the depth values back. */
11911     hr = IDirect3DDevice9_BeginScene(device);
11912     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11913     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11914     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11915     hr = IDirect3DDevice9_EndScene(device);
11916     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11917
11918     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11919     {
11920         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11921         ok(color_match(color, expected_colors[i].color, 1),
11922                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11923                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11924     }
11925
11926     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11927     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11928
11929     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11930     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11931     IDirect3DSurface9_Release(original_ds);
11932     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11933     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11934     IDirect3DTexture9_Release(texture);
11935     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11936     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11937     IDirect3DPixelShader9_Release(ps);
11938
11939     IDirect3DSurface9_Release(original_rt);
11940     IDirect3DSurface9_Release(rt);
11941 }
11942
11943 static void shadow_test(IDirect3DDevice9 *device)
11944 {
11945     static const DWORD ps_code[] =
11946     {
11947         0xffff0200,                                                             /* ps_2_0                       */
11948         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11949         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11950         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11951         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11952         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11953         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11954         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11955         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11956         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11957         0x0000ffff,                                                             /* end                          */
11958     };
11959     struct
11960     {
11961         D3DFORMAT format;
11962         const char *name;
11963     }
11964     formats[] =
11965     {
11966         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11967         {D3DFMT_D32,            "D3DFMT_D32"},
11968         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11969         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11970         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11971         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11972         {D3DFMT_D16,            "D3DFMT_D16"},
11973         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11974         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11975     };
11976     struct
11977     {
11978         float x, y, z;
11979         float s, t, p, q;
11980     }
11981     quad[] =
11982     {
11983         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11984         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11985         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11986         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11987     };
11988     struct
11989     {
11990         UINT x, y;
11991         D3DCOLOR color;
11992     }
11993     expected_colors[] =
11994     {
11995         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11996         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11997         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11998         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11999         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12000         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12001         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12002         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12003     };
12004
12005     IDirect3DSurface9 *original_ds, *original_rt, *rt;
12006     IDirect3DPixelShader9 *ps;
12007     IDirect3D9 *d3d9;
12008     D3DCAPS9 caps;
12009     HRESULT hr;
12010     UINT i;
12011
12012     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12013     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12014     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12015     {
12016         skip("No pixel shader 2.0 support, skipping shadow test.\n");
12017         return;
12018     }
12019
12020     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12021     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12022     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12023     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12024     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12025     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12026
12027     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12028             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12029     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12030     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12031     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12032
12033     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12034     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12035     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12036     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12037     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12038     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12039     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12040     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12041     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12042     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12043
12044     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12045     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12046     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12047     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12048     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12049     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12050     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12051     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12052     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12053     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12054
12055     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12056     {
12057         D3DFORMAT format = formats[i].format;
12058         IDirect3DTexture9 *texture;
12059         IDirect3DSurface9 *ds;
12060         unsigned int j;
12061
12062         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12063                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12064         if (FAILED(hr)) continue;
12065
12066         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12067                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12068         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12069
12070         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12071         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12072
12073         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12074         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12075
12076         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12077         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12078
12079         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12080         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12081
12082         /* Setup the depth/stencil surface. */
12083         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12084         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12085
12086         hr = IDirect3DDevice9_BeginScene(device);
12087         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12088         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12089         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12090         hr = IDirect3DDevice9_EndScene(device);
12091         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12092
12093         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12094         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12095         IDirect3DSurface9_Release(ds);
12096
12097         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12098         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12099
12100         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12101         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12102
12103         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12104         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12105
12106         /* Do the actual shadow mapping. */
12107         hr = IDirect3DDevice9_BeginScene(device);
12108         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12109         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12110         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12111         hr = IDirect3DDevice9_EndScene(device);
12112         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12113
12114         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12115         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12116         IDirect3DTexture9_Release(texture);
12117
12118         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12119         {
12120             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12121             ok(color_match(color, expected_colors[j].color, 0),
12122                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12123                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12124                     formats[i].name, color);
12125         }
12126
12127         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12128         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12129     }
12130
12131     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12132     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12133     IDirect3DPixelShader9_Release(ps);
12134
12135     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12136     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12137     IDirect3DSurface9_Release(original_ds);
12138
12139     IDirect3DSurface9_Release(original_rt);
12140     IDirect3DSurface9_Release(rt);
12141
12142     IDirect3D9_Release(d3d9);
12143 }
12144
12145 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12146 {
12147     const struct vertex quad1[] =
12148     {
12149         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12150         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12151         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12152         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12153     };
12154     const struct vertex quad2[] =
12155     {
12156         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12157         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12158         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12159         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12160     };
12161     D3DCOLOR color;
12162     HRESULT hr;
12163
12164     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12165     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12166
12167     hr = IDirect3DDevice9_BeginScene(device);
12168     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12169
12170     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12171     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12172
12173     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12174     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12175     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12176     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12177
12178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12179     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12180     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12181     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12182
12183     hr = IDirect3DDevice9_EndScene(device);
12184     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12185
12186     color = getPixelColor(device, 1, 240);
12187     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12188     color = getPixelColor(device, 638, 240);
12189     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12190
12191     color = getPixelColor(device, 1, 241);
12192     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12193     color = getPixelColor(device, 638, 241);
12194     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12195 }
12196
12197 static void clip_planes_test(IDirect3DDevice9 *device)
12198 {
12199     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12200
12201     const DWORD shader_code[] = {
12202         0xfffe0200, /* vs_2_0 */
12203         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12204         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12205         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12206         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12207         0x0000ffff /* end */
12208     };
12209     IDirect3DVertexShader9 *shader;
12210
12211     IDirect3DTexture9 *offscreen = NULL;
12212     IDirect3DSurface9 *offscreen_surface, *original_rt;
12213     HRESULT hr;
12214
12215     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12216     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12217
12218     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12219     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12220     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12221     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12222     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12223     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12224     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12225     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12226
12227     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12228     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12229     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12230     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12231
12232     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12233
12234     clip_planes(device, "Onscreen FFP");
12235
12236     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12237     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12238     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12239     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12240     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12241     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12242
12243     clip_planes(device, "Offscreen FFP");
12244
12245     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12246     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12247
12248     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12250     hr = IDirect3DDevice9_SetVertexShader(device, shader);
12251     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12252
12253     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12254     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12255
12256     clip_planes(device, "Onscreen vertex shader");
12257
12258     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12259     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12260
12261     clip_planes(device, "Offscreen vertex shader");
12262
12263     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12264     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12265
12266     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12267     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12268     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12269     IDirect3DVertexShader9_Release(shader);
12270     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12272     IDirect3DSurface9_Release(original_rt);
12273     IDirect3DSurface9_Release(offscreen_surface);
12274     IDirect3DTexture9_Release(offscreen);
12275 }
12276
12277 static void fp_special_test(IDirect3DDevice9 *device)
12278 {
12279     static const DWORD vs_header[] =
12280     {
12281         0xfffe0200,                                                             /* vs_2_0                       */
12282         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12283         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12284         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12285     };
12286
12287     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12288     static const DWORD vs_pow[] =
12289             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12290     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12291     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12292     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12293     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12294     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12295     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12296             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12297
12298     static const DWORD vs_footer[] =
12299     {
12300         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12301         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12302         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12303         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12304         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12305         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12306         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12307         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12308         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12309         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12310         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12311         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12312         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12313         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12314         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12315         0x0000ffff,                                                             /* end                          */
12316     };
12317
12318     static const struct
12319     {
12320         const char *name;
12321         const DWORD *ops;
12322         DWORD size;
12323         D3DCOLOR r600;
12324         D3DCOLOR nv40;
12325         D3DCOLOR nv50;
12326     }
12327     vs_body[] =
12328     {
12329         /* The basic ideas here are:
12330          *     2.0 * +/-INF == +/-INF
12331          *     NAN != NAN
12332          *
12333          * The vertex shader value is written to the red component, with 0.0
12334          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12335          * result in 0x00. The pixel shader value is written to the green
12336          * component, but here 0.0 also results in 0x00. The actual value is
12337          * written to the blue component.
12338          *
12339          * There are considerable differences between graphics cards in how
12340          * these are handled, but pow and nrm never generate INF or NAN. */
12341         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12342         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12343         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12344         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12345         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12346         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12347         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12348         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12349     };
12350
12351     static const DWORD ps_code[] =
12352     {
12353         0xffff0200,                                                             /* ps_2_0                       */
12354         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12355         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12356         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12357         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12358         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12359         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12360         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12361         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12362         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12363         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12364         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12365         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12366         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12367         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12368         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12369         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12370         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12371         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12372         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12373         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12374         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12375         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12376         0x0000ffff,                                                             /* end                          */
12377     };
12378
12379     struct
12380     {
12381         float x, y, z;
12382         float s;
12383     }
12384     quad[] =
12385     {
12386         { -1.0f,  1.0f, 0.0f, 0.0f},
12387         {  1.0f,  1.0f, 1.0f, 0.0f},
12388         { -1.0f, -1.0f, 0.0f, 0.0f},
12389         {  1.0f, -1.0f, 1.0f, 0.0f},
12390     };
12391
12392     IDirect3DPixelShader9 *ps;
12393     UINT body_size = 0;
12394     DWORD *vs_code;
12395     D3DCAPS9 caps;
12396     HRESULT hr;
12397     UINT i;
12398
12399     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12400     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12401     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12402     {
12403         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12404         return;
12405     }
12406
12407     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12408     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12409
12410     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12411     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12412     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12413     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12414
12415     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12416     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12417
12418     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12419     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12420
12421     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12422     {
12423         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12424     }
12425
12426     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12427     memcpy(vs_code, vs_header, sizeof(vs_header));
12428
12429     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12430     {
12431         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12432         IDirect3DVertexShader9 *vs;
12433         D3DCOLOR color;
12434
12435         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12436         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12437         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12438
12439         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12440         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12441         hr = IDirect3DDevice9_SetVertexShader(device, vs);
12442         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12443
12444         hr = IDirect3DDevice9_BeginScene(device);
12445         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12447         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12448         hr = IDirect3DDevice9_EndScene(device);
12449         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12450
12451         color = getPixelColor(device, 320, 240);
12452         ok(color_match(color, vs_body[i].r600, 1)
12453                 || color_match(color, vs_body[i].nv40, 1)
12454                 || color_match(color, vs_body[i].nv50, 1),
12455                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12456                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12457
12458         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12459         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12460
12461         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12462         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12463         IDirect3DVertexShader9_Release(vs);
12464     }
12465
12466     HeapFree(GetProcessHeap(), 0, vs_code);
12467
12468     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12469     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12470     IDirect3DPixelShader9_Release(ps);
12471 }
12472
12473 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12474 {
12475     IDirect3D9 *d3d;
12476     IDirect3DSurface9 *rt, *backbuffer;
12477     IDirect3DTexture9 *texture;
12478     HRESULT hr;
12479     int i;
12480     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12481     static const struct
12482     {
12483         D3DFORMAT fmt;
12484         const char *name;
12485     }
12486     formats[] =
12487     {
12488         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12489         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12490         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12491         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12492         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12493     };
12494     static const struct
12495     {
12496         float x, y, z;
12497         float u, v;
12498     }
12499     quad[] =
12500     {
12501         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12502         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12503         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12504         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12505     };
12506
12507     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12508     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12509     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12510     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12511     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12512     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12513     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12514     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12516     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12517
12518     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12519     {
12520         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12521                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12522         {
12523             skip("Format %s not supported as render target, skipping test.\n",
12524                     formats[i].name);
12525             continue;
12526         }
12527
12528         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12529                                             D3DPOOL_DEFAULT, &texture, NULL);
12530         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12531         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12532         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12533
12534         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12535         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12536         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12537         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12538         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12539         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12540
12541         hr = IDirect3DDevice9_BeginScene(device);
12542         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12543         if(SUCCEEDED(hr))
12544         {
12545             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12546             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12547             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12548             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12549             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12550             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12551
12552             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12553             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12554             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12555             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12556             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12557             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12558             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12559             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12560             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12561             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12562             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12563             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12564
12565             hr = IDirect3DDevice9_EndScene(device);
12566             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12567         }
12568
12569         IDirect3DSurface9_Release(rt);
12570         IDirect3DTexture9_Release(texture);
12571
12572         color = getPixelColor(device, 360, 240);
12573         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12574                                     D3DUSAGE_QUERY_SRGBWRITE,
12575                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12576         {
12577             /* Big slop for R5G6B5 */
12578             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12579                 formats[i].name, color_srgb, color);
12580         }
12581         else
12582         {
12583             /* Big slop for R5G6B5 */
12584             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12585                 formats[i].name, color_rgb, color);
12586         }
12587
12588         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12589         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12590     }
12591
12592     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12593     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12594
12595     IDirect3D9_Release(d3d);
12596     IDirect3DSurface9_Release(backbuffer);
12597 }
12598
12599 static void ds_size_test(IDirect3DDevice9 *device)
12600 {
12601     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12602     HRESULT hr;
12603     DWORD num_passes;
12604     struct
12605     {
12606         float x, y, z;
12607     }
12608     quad[] =
12609     {
12610         {-1.0,  -1.0,   0.0 },
12611         {-1.0,   1.0,   0.0 },
12612         { 1.0,  -1.0,   0.0 },
12613         { 1.0,   1.0,   0.0 }
12614     };
12615
12616     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12617     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12618     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12619     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12620     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12621     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12622
12623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12624     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12626     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12627     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12628     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12629     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12630     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12631     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12632     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12633     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12634     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12635     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12637     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12638     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12639     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12640     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12641
12642     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12643      * but does not change the surface's contents. */
12644     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12645     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12646     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12647     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12648     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12649     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12650
12651     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12652
12653     /* Turning on any depth-related state results in a ValidateDevice failure */
12654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12655     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12656     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12657     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12658         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12660     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12662     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12663     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12664     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12665         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12666
12667     /* Try to draw with the device in an invalid state */
12668     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12669     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12670     hr = IDirect3DDevice9_BeginScene(device);
12671     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12672     if(SUCCEEDED(hr))
12673     {
12674         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12675         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12676         hr = IDirect3DDevice9_EndScene(device);
12677         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12678
12679         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12680          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12681          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12682     }
12683
12684     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12685     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12686     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12687     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12688     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12689     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12690
12691     IDirect3DSurface9_Release(readback);
12692     IDirect3DSurface9_Release(ds);
12693     IDirect3DSurface9_Release(rt);
12694     IDirect3DSurface9_Release(old_rt);
12695     IDirect3DSurface9_Release(old_ds);
12696 }
12697
12698 static void unbound_sampler_test(IDirect3DDevice9 *device)
12699 {
12700     HRESULT hr;
12701     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12702     IDirect3DSurface9 *rt, *old_rt;
12703     DWORD color;
12704
12705     static const DWORD ps_code[] =
12706     {
12707         0xffff0200,                                     /* ps_2_0           */
12708         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12709         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12710         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12711         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12712         0x0000ffff,                                     /* end              */
12713     };
12714     static const DWORD ps_code_cube[] =
12715     {
12716         0xffff0200,                                     /* ps_2_0           */
12717         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12718         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12719         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12720         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12721         0x0000ffff,                                     /* end              */
12722     };
12723     static const DWORD ps_code_volume[] =
12724     {
12725         0xffff0200,                                     /* ps_2_0           */
12726         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12727         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12728         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12729         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12730         0x0000ffff,                                     /* end              */
12731     };
12732
12733     static const struct
12734     {
12735         float x, y, z;
12736         float u, v;
12737     }
12738     quad[] =
12739     {
12740         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12741         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12742         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12743         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12744     };
12745
12746     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12747     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12748
12749     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12750     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12751     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12752     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12753     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12754     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12755
12756     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12757     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12758
12759     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12760     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12761
12762     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12763     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12764
12765     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12766     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12767
12768     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12769     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12770
12771     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12772     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12773
12774     hr = IDirect3DDevice9_BeginScene(device);
12775     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12776     if(SUCCEEDED(hr))
12777     {
12778         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12779         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12780
12781         hr = IDirect3DDevice9_EndScene(device);
12782         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12783     }
12784
12785     color = getPixelColorFromSurface(rt, 32, 32);
12786     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12787
12788     /* Now try with a cube texture */
12789     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12790     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12791
12792     hr = IDirect3DDevice9_BeginScene(device);
12793     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12794     if (SUCCEEDED(hr))
12795     {
12796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12797         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12798
12799         hr = IDirect3DDevice9_EndScene(device);
12800         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12801     }
12802
12803     color = getPixelColorFromSurface(rt, 32, 32);
12804     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12805
12806     /* And then with a volume texture */
12807     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12808     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12809
12810     hr = IDirect3DDevice9_BeginScene(device);
12811     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12812     if (SUCCEEDED(hr))
12813     {
12814         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12815         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12816
12817         hr = IDirect3DDevice9_EndScene(device);
12818         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12819     }
12820
12821     color = getPixelColorFromSurface(rt, 32, 32);
12822     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12823
12824     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12825     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12826
12827     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12828     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12829
12830     IDirect3DSurface9_Release(rt);
12831     IDirect3DSurface9_Release(old_rt);
12832     IDirect3DPixelShader9_Release(ps);
12833     IDirect3DPixelShader9_Release(ps_cube);
12834     IDirect3DPixelShader9_Release(ps_volume);
12835 }
12836
12837 static void update_surface_test(IDirect3DDevice9 *device)
12838 {
12839     static const BYTE blocks[][8] =
12840     {
12841         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12842         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12843         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12844         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12845         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12846         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12847         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12848     };
12849     static const struct
12850     {
12851         UINT x, y;
12852         D3DCOLOR color;
12853     }
12854     expected_colors[] =
12855     {
12856         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12857         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12858         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12859         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12860         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12861         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12862         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12863     };
12864     static const struct
12865     {
12866         float x, y, z, w;
12867         float u, v;
12868     }
12869     tri[] =
12870     {
12871         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12872         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12873         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12874     };
12875     static const RECT rect_2x2 = {0, 0, 2, 2};
12876     static const struct
12877     {
12878         UINT src_level;
12879         UINT dst_level;
12880         const RECT *r;
12881         HRESULT hr;
12882     }
12883     block_size_tests[] =
12884     {
12885         {1, 0, NULL,      D3D_OK},
12886         {0, 1, NULL,      D3DERR_INVALIDCALL},
12887         {5, 4, NULL,      D3DERR_INVALIDCALL},
12888         {4, 5, NULL,      D3DERR_INVALIDCALL},
12889         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12890         {5, 5, &rect_2x2, D3D_OK},
12891     };
12892
12893     IDirect3DSurface9 *src_surface, *dst_surface;
12894     IDirect3DTexture9 *src_tex, *dst_tex;
12895     IDirect3D9 *d3d;
12896     UINT count, i;
12897     HRESULT hr;
12898
12899     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12900     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12901
12902     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12903             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12904     IDirect3D9_Release(d3d);
12905     if (FAILED(hr))
12906     {
12907         skip("DXT1 not supported, skipping test.\n");
12908         return;
12909     }
12910
12911     IDirect3D9_Release(d3d);
12912
12913     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12914     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12915     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12916     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12917
12918     count = IDirect3DTexture9_GetLevelCount(src_tex);
12919     ok(count == 7, "Got level count %u, expected 7.\n", count);
12920
12921     for (i = 0; i < count; ++i)
12922     {
12923         UINT row_count, block_count, x, y;
12924         D3DSURFACE_DESC desc;
12925         BYTE *row, *block;
12926         D3DLOCKED_RECT r;
12927
12928         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12929         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12930
12931         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12932         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12933
12934         row_count = ((desc.Height + 3) & ~3) / 4;
12935         block_count = ((desc.Width + 3) & ~3) / 4;
12936         row = r.pBits;
12937
12938         for (y = 0; y < row_count; ++y)
12939         {
12940             block = row;
12941             for (x = 0; x < block_count; ++x)
12942             {
12943                 memcpy(block, blocks[i], sizeof(blocks[i]));
12944                 block += sizeof(blocks[i]);
12945             }
12946             row += r.Pitch;
12947         }
12948
12949         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12950         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12951     }
12952
12953     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12954     {
12955         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12956         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12957         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12958         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12959
12960         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12961         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12962                 hr, i, block_size_tests[i].hr);
12963
12964         IDirect3DSurface9_Release(dst_surface);
12965         IDirect3DSurface9_Release(src_surface);
12966     }
12967
12968     for (i = 0; i < count; ++i)
12969     {
12970         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12971         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12972         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12973         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12974
12975         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12976         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12977
12978         IDirect3DSurface9_Release(dst_surface);
12979         IDirect3DSurface9_Release(src_surface);
12980     }
12981
12982     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12983     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12984     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12985     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12986     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12987     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12988     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12989     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12990     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12991     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12993     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12994
12995     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12996     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12997
12998     hr = IDirect3DDevice9_BeginScene(device);
12999     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13000     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
13001     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13002     hr = IDirect3DDevice9_EndScene(device);
13003     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13004
13005     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13006     {
13007         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13008         ok(color_match(color, expected_colors[i].color, 0),
13009                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13010                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13011     }
13012
13013     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13014     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13015
13016     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13017     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13018     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13019     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13020     IDirect3DTexture9_Release(dst_tex);
13021     IDirect3DTexture9_Release(src_tex);
13022 }
13023
13024 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13025 {
13026     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13027     IDirect3D9 *d3d9;
13028     HRESULT hr;
13029
13030     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13031     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13032     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13033             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13034     IDirect3D9_Release(d3d9);
13035     if (FAILED(hr))
13036     {
13037         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13038         return;
13039     }
13040
13041     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13042             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13043     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13044     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13045             D3DPOOL_SYSTEMMEM, &readback, NULL);
13046     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13047
13048     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13049     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13050     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13051     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13052
13053     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13054     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13055     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13056     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13057
13058     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13059     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13060     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13061     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13062
13063     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13064     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13065     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13066     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13067
13068     IDirect3DSurface9_Release(original_ds);
13069     IDirect3DSurface9_Release(original_rt);
13070     IDirect3DSurface9_Release(readback);
13071     IDirect3DSurface9_Release(rt);
13072 }
13073
13074 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13075 {
13076     IDirect3DDevice9 *device = 0;
13077     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13078     D3DCAPS9 caps;
13079     HRESULT hr;
13080     D3DPRESENT_PARAMETERS present_parameters;
13081     unsigned int i;
13082     static const struct
13083     {
13084         float x, y, z;
13085         D3DCOLOR color;
13086     }
13087     quad_1[] =
13088     {
13089         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13090         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13091         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13092         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13093     },
13094     quad_2[] =
13095     {
13096         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13097         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13098         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13099         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13100     };
13101     static const struct
13102     {
13103         UINT x, y;
13104         D3DCOLOR color;
13105     }
13106     expected_colors[] =
13107     {
13108         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13109         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13110         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13111         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13112         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13113         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13114         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13115         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13116     };
13117
13118     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13119             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13120     if (FAILED(hr))
13121     {
13122         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13123         return;
13124     }
13125     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13126             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13127     if (FAILED(hr))
13128     {
13129         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13130         return;
13131     }
13132
13133     ZeroMemory(&present_parameters, sizeof(present_parameters));
13134     present_parameters.Windowed = TRUE;
13135     present_parameters.hDeviceWindow = create_window();
13136     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13137     present_parameters.BackBufferWidth = 640;
13138     present_parameters.BackBufferHeight = 480;
13139     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13140     present_parameters.EnableAutoDepthStencil = TRUE;
13141     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13142     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13143
13144     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13145             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13146             &present_parameters, &device);
13147     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13148
13149     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13150     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13151     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13152     {
13153         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13154         goto cleanup;
13155     }
13156
13157     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13158             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13159     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13160     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13161             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13162     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13163
13164     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13165     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13166     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13167     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13168
13169     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13170     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13172     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13173     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13174     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13176     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13177     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13178     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13179
13180     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13181     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13182
13183     /* Render onscreen and then offscreen */
13184     hr = IDirect3DDevice9_BeginScene(device);
13185     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13186     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13187     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13188     hr = IDirect3DDevice9_EndScene(device);
13189     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13190
13191     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13192     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13193     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13194     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13195
13196     hr = IDirect3DDevice9_BeginScene(device);
13197     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13198     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13199     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13200     hr = IDirect3DDevice9_EndScene(device);
13201     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13202
13203     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13204     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13205
13206     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13207     {
13208         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13209         ok(color_match(color, expected_colors[i].color, 1),
13210                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13211                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13212     }
13213
13214     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13215     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13216     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13217     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13218
13219     /* Render offscreen and then onscreen */
13220     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13221     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13222     IDirect3DSurface9_Release(ds);
13223     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13224             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13225     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13226     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13227
13228     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13229     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13230
13231     hr = IDirect3DDevice9_BeginScene(device);
13232     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13233     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13234     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13235     hr = IDirect3DDevice9_EndScene(device);
13236     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13237
13238     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13239     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13240     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13241     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13242
13243     hr = IDirect3DDevice9_BeginScene(device);
13244     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13245     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13246     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13247     hr = IDirect3DDevice9_EndScene(device);
13248     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13249
13250     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13251     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13252
13253     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13254     {
13255         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13256         ok(color_match(color, expected_colors[i].color, 1),
13257                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13258                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13259     }
13260
13261     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13262     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13263
13264     IDirect3DSurface9_Release(ds);
13265     IDirect3DSurface9_Release(readback);
13266     IDirect3DSurface9_Release(rt);
13267     IDirect3DSurface9_Release(original_rt);
13268     cleanup_device(device);
13269
13270     ZeroMemory(&present_parameters, sizeof(present_parameters));
13271     present_parameters.Windowed = TRUE;
13272     present_parameters.hDeviceWindow = create_window();
13273     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13274     present_parameters.BackBufferWidth = 640;
13275     present_parameters.BackBufferHeight = 480;
13276     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13277     present_parameters.EnableAutoDepthStencil = TRUE;
13278     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13279     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13280
13281     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13282             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13283             &present_parameters, &device);
13284     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13285
13286     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13287     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13288
13289     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13290             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13291     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13292     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13293             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13294     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13295     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13296             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13297     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13298
13299     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13300     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13301     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13302     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13303     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13304     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13305     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13306     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13307
13308     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13309     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13310     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13311     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13313     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13314     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13315     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13316     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13317     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13318
13319     /* Render to a multisampled offscreen frame buffer and then blit to
13320      * the onscreen (not multisampled) frame buffer. */
13321     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13322     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13323
13324     hr = IDirect3DDevice9_BeginScene(device);
13325     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13326     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13327     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13328     hr = IDirect3DDevice9_EndScene(device);
13329     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13330
13331     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13332     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13333     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13334     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13335
13336     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13337     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13338     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13339     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13340
13341     hr = IDirect3DDevice9_BeginScene(device);
13342     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13343     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13344     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13345     hr = IDirect3DDevice9_EndScene(device);
13346     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13347
13348     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13349     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13350
13351     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13352     {
13353         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13354         if (i % 4 < 2)
13355             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13356                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13357                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13358         else
13359             ok(color_match(color, expected_colors[i].color, 1),
13360                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13361                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13362     }
13363
13364     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13365     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13366
13367     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13368     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13369     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13370     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13371
13372     IDirect3DSurface9_Release(original_ds);
13373     IDirect3DSurface9_Release(original_rt);
13374     IDirect3DSurface9_Release(ds);
13375     IDirect3DSurface9_Release(readback);
13376     IDirect3DSurface9_Release(rt);
13377 cleanup:
13378     cleanup_device(device);
13379 }
13380
13381 static void resz_test(IDirect3D9 *d3d9)
13382 {
13383     IDirect3DDevice9 *device = 0;
13384     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13385     D3DCAPS9 caps;
13386     HRESULT hr;
13387     D3DPRESENT_PARAMETERS present_parameters;
13388     unsigned int i;
13389     static const DWORD ps_code[] =
13390     {
13391         0xffff0200,                                                             /* ps_2_0                       */
13392         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13393         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13394         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13395         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13396         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13397         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13398         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13399         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13400         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13401         0x0000ffff,                                                             /* end                          */
13402     };
13403     struct
13404     {
13405         float x, y, z;
13406         float s, t, p, q;
13407     }
13408     quad[] =
13409     {
13410         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13411         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13412         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13413         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13414     };
13415     struct
13416     {
13417         UINT x, y;
13418         D3DCOLOR color;
13419     }
13420     expected_colors[] =
13421     {
13422         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13423         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13424         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13425         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13426         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13427         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13428         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13429         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13430     };
13431     IDirect3DTexture9 *texture;
13432     IDirect3DPixelShader9 *ps;
13433     DWORD value;
13434
13435     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13436             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13437     if (FAILED(hr))
13438     {
13439         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13440         return;
13441     }
13442     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13443             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13444     if (FAILED(hr))
13445     {
13446         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13447         return;
13448     }
13449
13450     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13451             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13452     if (FAILED(hr))
13453     {
13454         skip("No INTZ support, skipping RESZ test.\n");
13455         return;
13456     }
13457
13458     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13459             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13460     if (FAILED(hr))
13461     {
13462         skip("No RESZ support, skipping RESZ test.\n");
13463         return;
13464     }
13465
13466     ZeroMemory(&present_parameters, sizeof(present_parameters));
13467     present_parameters.Windowed = TRUE;
13468     present_parameters.hDeviceWindow = create_window();
13469     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13470     present_parameters.BackBufferWidth = 640;
13471     present_parameters.BackBufferHeight = 480;
13472     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13473     present_parameters.EnableAutoDepthStencil = FALSE;
13474     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13475     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13476
13477     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13478             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13479     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13480
13481     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13482     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13483     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13484     {
13485         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13486         cleanup_device(device);
13487         return;
13488     }
13489     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13490     {
13491         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13492         cleanup_device(device);
13493         return;
13494     }
13495
13496     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13497     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13498
13499     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13500             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13501     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13502     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13503             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13504     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13505             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13506     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13507
13508     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13509             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13510     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13511     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13512     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13513     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13514     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13515     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13516     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13517     IDirect3DSurface9_Release(intz_ds);
13518     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13519     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13520
13521     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13522     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13523     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13524     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13525     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13526     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13527     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13528     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13529     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13530     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13531
13532     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13533     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13534     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13535     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13536     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13537     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13538     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13539     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13540     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13541     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13542
13543     /* Render offscreen (multisampled), blit the depth buffer
13544      * into the INTZ texture and then check its contents */
13545     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13546     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13547     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13548     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13549     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13550     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13551
13552     hr = IDirect3DDevice9_BeginScene(device);
13553     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13554     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13555     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13556
13557     /* The destination depth texture has to be bound to sampler 0 */
13558     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13559     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13560
13561     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13563     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13564     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13565     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13566     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13567     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13568     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13569     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13571     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13573     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13575     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13576
13577     /* The actual multisampled depth buffer resolve happens here */
13578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13579     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13580     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13581     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13582
13583     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13584     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13585     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13586     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13587
13588     /* Read the depth values back */
13589     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13590     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13591     hr = IDirect3DDevice9_EndScene(device);
13592     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13593
13594     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13595     {
13596         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13597         ok(color_match(color, expected_colors[i].color, 1),
13598                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13599                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13600     }
13601
13602     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13603     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13604
13605     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13606     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13607     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13608     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13609     IDirect3DSurface9_Release(ds);
13610     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13611     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13612     IDirect3DTexture9_Release(texture);
13613     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13614     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13615     IDirect3DPixelShader9_Release(ps);
13616     IDirect3DSurface9_Release(readback);
13617     IDirect3DSurface9_Release(original_rt);
13618     IDirect3DSurface9_Release(rt);
13619     cleanup_device(device);
13620
13621
13622     ZeroMemory(&present_parameters, sizeof(present_parameters));
13623     present_parameters.Windowed = TRUE;
13624     present_parameters.hDeviceWindow = create_window();
13625     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13626     present_parameters.BackBufferWidth = 640;
13627     present_parameters.BackBufferHeight = 480;
13628     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13629     present_parameters.EnableAutoDepthStencil = TRUE;
13630     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13631     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13632
13633     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13634             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13635     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13636
13637     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13638     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13639     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13640     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13641     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13642             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13643     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13644     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13645             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13646     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13647     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13648     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13649     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13650     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13651     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13652     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13653     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13654     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13655     IDirect3DSurface9_Release(intz_ds);
13656     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13657     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13658
13659     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13660     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13662     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13664     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13666     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13668     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13669
13670     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13671     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13672     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13673     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13675     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13676     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13677     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13678     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13679     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13680
13681     /* Render onscreen, blit the depth buffer into the INTZ texture
13682      * and then check its contents */
13683     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13684     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13685     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13686     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13687     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13688     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13689
13690     hr = IDirect3DDevice9_BeginScene(device);
13691     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13692     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13693     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13694     hr = IDirect3DDevice9_EndScene(device);
13695     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13696
13697     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13698     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13699
13700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13701     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13703     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13704     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13705     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13706     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13707     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13708     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13709     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13710     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13711     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13712     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13713     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13714
13715     /* The actual multisampled depth buffer resolve happens here */
13716     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13717     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13718     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13719     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13720
13721     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13722     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13723     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13724     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13725
13726     /* Read the depth values back */
13727     hr = IDirect3DDevice9_BeginScene(device);
13728     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13729     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13730     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13731     hr = IDirect3DDevice9_EndScene(device);
13732     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13733
13734     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13735     {
13736         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13737         ok(color_match(color, expected_colors[i].color, 1),
13738                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13739                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13740     }
13741
13742     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13743     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13744
13745
13746     /* Test edge cases - try with no texture at all */
13747     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13748     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13749     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13750     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13751
13752     hr = IDirect3DDevice9_BeginScene(device);
13753     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13754     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13755     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13756     hr = IDirect3DDevice9_EndScene(device);
13757     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13758
13759     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13760     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13761
13762     /* With a non-multisampled depth buffer */
13763     IDirect3DSurface9_Release(ds);
13764     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13765             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13766
13767     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13768     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13769     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13770     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13771     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13772     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13773
13774     hr = IDirect3DDevice9_BeginScene(device);
13775     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13776     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13777     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13778
13779     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13780     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13781
13782     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13783     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13784     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13785     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13786     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13787     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13788     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13789     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13790     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13791     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13792     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13793     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13794     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13795     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13796     hr = IDirect3DDevice9_EndScene(device);
13797     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13798
13799     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13800     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13801
13802     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13803     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13804
13805     /* Read the depth values back. */
13806     hr = IDirect3DDevice9_BeginScene(device);
13807     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13808     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13809     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13810     hr = IDirect3DDevice9_EndScene(device);
13811     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13812
13813     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13814     {
13815         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13816         ok(color_match(color, expected_colors[i].color, 1),
13817                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13818                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13819     }
13820
13821     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13822     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13823
13824     /* Without a current depth-stencil buffer set */
13825     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13826     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13827     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13828     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13829
13830     hr = IDirect3DDevice9_BeginScene(device);
13831     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13832     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13833     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13834     hr = IDirect3DDevice9_EndScene(device);
13835     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13836
13837     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13838     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13839
13840     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13841     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13842     IDirect3DSurface9_Release(ds);
13843     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13844     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13845     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13846     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13847     IDirect3DTexture9_Release(texture);
13848     IDirect3DPixelShader9_Release(ps);
13849     IDirect3DSurface9_Release(readback);
13850     IDirect3DSurface9_Release(original_rt);
13851     cleanup_device(device);
13852 }
13853
13854 static void zenable_test(IDirect3DDevice9 *device)
13855 {
13856     static const struct
13857     {
13858         struct vec4 position;
13859         D3DCOLOR diffuse;
13860     }
13861     tquad[] =
13862     {
13863         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13864         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13865         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13866         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13867     };
13868     D3DCOLOR color;
13869     D3DCAPS9 caps;
13870     HRESULT hr;
13871     UINT x, y;
13872     UINT i, j;
13873
13874     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13875     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13876     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13877     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13878
13879     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13880     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13881     hr = IDirect3DDevice9_BeginScene(device);
13882     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13883     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13884     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13885     hr = IDirect3DDevice9_EndScene(device);
13886     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13887
13888     for (i = 0; i < 4; ++i)
13889     {
13890         for (j = 0; j < 4; ++j)
13891         {
13892             x = 80 * ((2 * j) + 1);
13893             y = 60 * ((2 * i) + 1);
13894             color = getPixelColor(device, x, y);
13895             ok(color_match(color, 0x0000ff00, 1),
13896                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13897         }
13898     }
13899
13900     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13901     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13902
13903     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13904     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13905
13906     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13907             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13908     {
13909         static const DWORD vs_code[] =
13910         {
13911             0xfffe0101,                                 /* vs_1_1           */
13912             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13913             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13914             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13915             0x0000ffff
13916         };
13917         static const DWORD ps_code[] =
13918         {
13919             0xffff0101,                                 /* ps_1_1           */
13920             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13921             0x0000ffff                                  /* end              */
13922         };
13923         static const struct vec3 quad[] =
13924         {
13925             {-1.0f, -1.0f, -0.5f},
13926             {-1.0f,  1.0f, -0.5f},
13927             { 1.0f, -1.0f,  1.5f},
13928             { 1.0f,  1.0f,  1.5f},
13929         };
13930         static const D3DCOLOR expected[] =
13931         {
13932             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13933             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13934             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13935             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13936         };
13937
13938         IDirect3DVertexShader9 *vs;
13939         IDirect3DPixelShader9 *ps;
13940
13941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13942         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13943         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13944         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13945         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13946         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13947         hr = IDirect3DDevice9_SetVertexShader(device, vs);
13948         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13949         hr = IDirect3DDevice9_SetPixelShader(device, ps);
13950         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13951
13952         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13953         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13954         hr = IDirect3DDevice9_BeginScene(device);
13955         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13956         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13957         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13958         hr = IDirect3DDevice9_EndScene(device);
13959         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13960
13961         for (i = 0; i < 4; ++i)
13962         {
13963             for (j = 0; j < 4; ++j)
13964             {
13965                 x = 80 * ((2 * j) + 1);
13966                 y = 60 * ((2 * i) + 1);
13967                 color = getPixelColor(device, x, y);
13968                 ok(color_match(color, expected[i * 4 + j], 1),
13969                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13970             }
13971         }
13972
13973         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13974         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13975
13976         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13977         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13978         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13979         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13980         IDirect3DPixelShader9_Release(ps);
13981         IDirect3DVertexShader9_Release(vs);
13982     }
13983 }
13984
13985 START_TEST(visual)
13986 {
13987     IDirect3D9 *d3d9;
13988     IDirect3DDevice9 *device_ptr;
13989     D3DCAPS9 caps;
13990     HRESULT hr;
13991     DWORD color;
13992
13993     d3d9_handle = LoadLibraryA("d3d9.dll");
13994     if (!d3d9_handle)
13995     {
13996         skip("Could not load d3d9.dll\n");
13997         return;
13998     }
13999
14000     device_ptr = init_d3d9();
14001     if (!device_ptr)
14002     {
14003         skip("Creating the device failed\n");
14004         return;
14005     }
14006
14007     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14008
14009     /* Check for the reliability of the returned data */
14010     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14011     if(FAILED(hr))
14012     {
14013         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14014         goto cleanup;
14015     }
14016
14017     color = getPixelColor(device_ptr, 1, 1);
14018     if(color !=0x00ff0000)
14019     {
14020         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14021         goto cleanup;
14022     }
14023     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14024
14025     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14026     if(FAILED(hr))
14027     {
14028         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14029         goto cleanup;
14030     }
14031
14032     color = getPixelColor(device_ptr, 639, 479);
14033     if(color != 0x0000ddee)
14034     {
14035         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14036         goto cleanup;
14037     }
14038     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14039
14040     /* Now execute the real tests */
14041     depth_clamp_test(device_ptr);
14042     stretchrect_test(device_ptr);
14043     lighting_test(device_ptr);
14044     clear_test(device_ptr);
14045     color_fill_test(device_ptr);
14046     fog_test(device_ptr);
14047     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14048     {
14049         test_cube_wrap(device_ptr);
14050     } else {
14051         skip("No cube texture support\n");
14052     }
14053     z_range_test(device_ptr);
14054     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14055     {
14056         maxmip_test(device_ptr);
14057     }
14058     else
14059     {
14060         skip("No mipmap support\n");
14061     }
14062     offscreen_test(device_ptr);
14063     ds_size_test(device_ptr);
14064     alpha_test(device_ptr);
14065     shademode_test(device_ptr);
14066     srgbtexture_test(device_ptr);
14067     release_buffer_test(device_ptr);
14068     float_texture_test(device_ptr);
14069     g16r16_texture_test(device_ptr);
14070     pixelshader_blending_test(device_ptr);
14071     texture_transform_flags_test(device_ptr);
14072     autogen_mipmap_test(device_ptr);
14073     fixed_function_decl_test(device_ptr);
14074     conditional_np2_repeat_test(device_ptr);
14075     fixed_function_bumpmap_test(device_ptr);
14076     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14077         stencil_cull_test(device_ptr);
14078     } else {
14079         skip("No two sided stencil support\n");
14080     }
14081     pointsize_test(device_ptr);
14082     tssargtemp_test(device_ptr);
14083     np2_stretch_rect_test(device_ptr);
14084     yuv_color_test(device_ptr);
14085     zwriteenable_test(device_ptr);
14086     alphatest_test(device_ptr);
14087     viewport_test(device_ptr);
14088
14089     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14090     {
14091         test_constant_clamp_vs(device_ptr);
14092         test_compare_instructions(device_ptr);
14093     }
14094     else skip("No vs_1_1 support\n");
14095
14096     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14097     {
14098         test_mova(device_ptr);
14099         loop_index_test(device_ptr);
14100         sincos_test(device_ptr);
14101         sgn_test(device_ptr);
14102         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14103             test_vshader_input(device_ptr);
14104             test_vshader_float16(device_ptr);
14105             stream_test(device_ptr);
14106         } else {
14107             skip("No vs_3_0 support\n");
14108         }
14109     }
14110     else skip("No vs_2_0 support\n");
14111
14112     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14113     {
14114         fog_with_shader_test(device_ptr);
14115     }
14116     else skip("No vs_2_0 and ps_2_0 support\n");
14117
14118     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14119     {
14120         texbem_test(device_ptr);
14121         texdepth_test(device_ptr);
14122         texkill_test(device_ptr);
14123         x8l8v8u8_test(device_ptr);
14124         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14125             constant_clamp_ps_test(device_ptr);
14126             cnd_test(device_ptr);
14127             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14128                 dp2add_ps_test(device_ptr);
14129                 unbound_sampler_test(device_ptr);
14130                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14131                     nested_loop_test(device_ptr);
14132                     pretransformed_varying_test(device_ptr);
14133                     vFace_register_test(device_ptr);
14134                     vpos_register_test(device_ptr);
14135                     multiple_rendertargets_test(device_ptr);
14136                 } else {
14137                     skip("No ps_3_0 or vs_3_0 support\n");
14138                 }
14139             } else {
14140                 skip("No ps_2_0 support\n");
14141             }
14142         }
14143     }
14144     else skip("No ps_1_1 support\n");
14145
14146     texop_test(device_ptr);
14147     texop_range_test(device_ptr);
14148     alphareplicate_test(device_ptr);
14149     dp3_alpha_test(device_ptr);
14150     depth_buffer_test(device_ptr);
14151     depth_buffer2_test(device_ptr);
14152     depth_blit_test(device_ptr);
14153     intz_test(device_ptr);
14154     shadow_test(device_ptr);
14155     fp_special_test(device_ptr);
14156     depth_bounds_test(device_ptr);
14157     srgbwrite_format_test(device_ptr);
14158     clip_planes_test(device_ptr);
14159     update_surface_test(device_ptr);
14160     multisample_get_rtdata_test(device_ptr);
14161     zenable_test(device_ptr);
14162
14163     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14164     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14165     cleanup_device(device_ptr);
14166     device_ptr = NULL;
14167
14168     multisampled_depth_buffer_test(d3d9);
14169     resz_test(d3d9);
14170
14171     IDirect3D9_Release(d3d9);
14172
14173 cleanup:
14174     cleanup_device(device_ptr);
14175 }